AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet. More...
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
568 :
569 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
570 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
572{
574 m_skipCheck = skipCheck;
575 m_selfContainer = nullptr;
577 m_executedCurrently = false;
580 m_comboTarget = nullptr;
581 m_delayStart = 0;
583
585 m_auraScaleMask = 0;
586 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
587
588 // Get data for type of attack
589 switch (m_spellInfo->DmgClass)
590 {
594 else
596 break;
599 break;
600 default:
601 // Wands
604 else
606 break;
607 }
608
609 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
610
612 // wand case
615 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
616
617 if (originalCasterGUID)
618 m_originalCasterGUID = originalCasterGUID;
619 else
621
624 else
625 {
628 m_originalCaster = nullptr;
629 }
630
632 _triggeredCastFlags = triggerFlags;
633 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
635
636 m_CastItem = nullptr;
637
638 unitTarget = nullptr;
639 itemTarget = nullptr;
640 gameObjTarget = nullptr;
641 destTarget = nullptr;
642 damage = 0;
646 m_damage = 0;
647 m_healing = 0;
648 m_procAttacker = 0;
649 m_procVictim = 0;
650 m_procEx = 0;
651 focusObject = nullptr;
652 m_cast_count = 0;
653 m_glyphIndex = 0;
654 m_preCastSpell = 0;
655 m_spellAura = nullptr;
656 _scriptsLoaded = false;
657
658 //Auto Shot & Shoot (wand)
660
661 m_runesState = 0;
662 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
663 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
664 m_timer = 0; // will set to castime in prepare
665 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
666 m_immediateHandled = false;
667
669
671
672 // Determine if spell can be reflected back to the caster
673 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
677
679 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
680
681 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
683
684 // xinef:
685 _spellTargetsSelected = false;
686
687 m_weaponItem = nullptr;
688}
#define sSpellMgr
Definition: SpellMgr.h:825
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:137
@ OFF_ATTACK
Definition: Unit.h:210
@ BASE_ATTACK
Definition: Unit.h:209
@ RANGED_ATTACK
Definition: Unit.h:211
@ DIMINISHING_LEVEL_1
Definition: Unit.h:263
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1637
@ DIMINISHING_NONE
Definition: SharedDefines.h:3258
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:816
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:461
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:517
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1548
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1547
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1143
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:622
SpellSchoolMask
Definition: SharedDefines.h:295
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:202
Definition: Item.h:220
bool IsPlayer() const
Definition: Object.h:197
Player * ToPlayer()
Definition: Object.h:198
bool IsInWorld() const
Definition: Object.h:104
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:511
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1190
uint32 getClassMask() const
Definition: Unit.h:767
Definition: Spell.h:94
Definition: Spell.h:211
Unit * m_comboTarget
Definition: Spell.h:542
int8 m_comboPointGain
Definition: Spell.h:543
GameObject * gameObjTarget
Definition: Spell.h:653
bool m_referencedFromCurrentSpell
Definition: Spell.h:644
bool m_canReflect
Definition: Spell.h:620
uint32 m_procVictim
Definition: Spell.h:675
Unit * m_originalCaster
Definition: Spell.h:608
bool m_needComboPoints
Definition: Spell.h:646
uint64 m_delayStart
Definition: Spell.h:638
bool _scriptsLoaded
Definition: Spell.h:726
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:767
int32 damage
Definition: Spell.h:655
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:656
int32 m_channeledDuration
Definition: Spell.h:619
Aura * m_spellAura
Definition: Spell.h:658
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:701
Unit *const m_caster
Definition: Spell.h:602
uint8 m_delayAtDamageCount
Definition: Spell.h:627
WeaponAttackType m_attackType
Definition: Spell.h:616
bool m_immediateHandled
Definition: Spell.h:641
uint32 m_spellState
Definition: Spell.h:763
ObjectGuid m_originalCasterGUID
Definition: Spell.h:606
void CleanupTargetList()
Definition: Spell.cpp:2372
int32 m_timer
Definition: Spell.h:764
int32 m_casttime
Definition: Spell.h:618
Item * itemTarget
Definition: Spell.h:652
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:668
bool m_executedCurrently
Definition: Spell.h:645
DiminishingLevels m_diminishLevel
Definition: Spell.h:661
float m_damageMultipliers[3]
Definition: Spell.h:648
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:781
uint8 m_auraScaleMask
Definition: Spell.h:775
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:622
bool m_skipCheck
Definition: Spell.h:774
int32 m_healing
Definition: Spell.h:669
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:683
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:651
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:615
SpellEvent * _spellEvent
Definition: Spell.h:766
bool _spellTargetsSelected
Definition: Spell.h:779
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:654
Spell ** m_selfContainer
Definition: Spell.h:610
uint8 m_applyMultiplierMask
Definition: Spell.h:647
DiminishingGroup m_diminishGroup
Definition: Spell.h:662
uint32 m_procEx
Definition: Spell.h:676
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:604
int32 m_powerCost
Definition: Spell.h:617
uint32 m_procAttacker
Definition: Spell.h:674
GameObject * focusObject
Definition: Spell.h:665
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:625
bool m_autoRepeat
Definition: Spell.h:624
bool IsPassive() const
Definition: SpellInfo.cpp:1097
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1265
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:875
bool IsPositive() const
Definition: SpellInfo.cpp:1236
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1282
uint32 DmgClass
Definition: SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1275
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
691{
692 // unload scripts
693 while (!m_loadedScripts.empty())
694 {
695 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
696 (*itr)->_Unload();
697 delete (*itr);
698 m_loadedScripts.erase(itr);
699 }
700
702 {
703 // Clean the reference to avoid later crash.
704 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
705 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
706 *m_selfContainer = nullptr;
707 }
708
709 delete m_spellValue;
710
712}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156
void CheckEffectExecuteData()
Definition: Spell.cpp:8481
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:741
uint32 Id
Definition: SpellInfo.h:320

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3800{
3801 // update pointers base at GUIDs to prevent access to non-existed already object
3802 if (!UpdatePointers())
3803 {
3804 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3805 cancel();
3806 return;
3807 }
3808
3809 // cancel at lost explicit target during cast
3811 {
3812 cancel();
3813 return;
3814 }
3815
3816 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3818 {
3820 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3822
3823 if (Unit* charm = m_caster->GetCharm())
3824 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3825 }
3826
3827 if (Player* playerCaster = m_caster->ToPlayer())
3828 {
3829 // now that we've done the basic check, now run the scripts
3830 // should be done before the spell is actually executed
3831 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3832
3833 // As of 3.0.2 pets begin attacking their owner's target immediately
3834 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3835 // This prevents spells such as Hunter's Mark from triggering pet attack
3836 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3838 if (!playerCaster->m_Controlled.empty())
3839 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3840 if (Unit* pet = *itr)
3841 if (pet->IsAlive() && pet->IsCreature())
3842 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3843 }
3844
3846
3850
3852
3853 Player* modOwner = m_caster->GetSpellModOwner();
3854 // skip check if done already (for instant cast spells for example)
3855 if (!skipCheck)
3856 {
3857 SpellCastResult castResult = CheckCast(false);
3858 if (castResult != SPELL_CAST_OK)
3859 {
3860 SendCastResult(castResult);
3861 SendInterrupted(0);
3862
3863 finish(false);
3864 SetExecutedCurrently(false);
3865 return;
3866 }
3867
3868 // additional check after cast bar completes (must not be in CheckCast)
3869 // if trade not complete then remember it in trade data
3871 {
3872 if (m_caster->IsPlayer())
3873 {
3874 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3875 {
3876 if (!my_trade->IsInAcceptProcess())
3877 {
3878 // Spell will be casted at completing the trade. Silently ignore at this place
3879 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3881 SendInterrupted(0);
3882
3883 finish(false);
3884 SetExecutedCurrently(false);
3885 return;
3886 }
3887 }
3888 }
3889 }
3890 }
3891
3892 if (modOwner)
3893 modOwner->SetSpellModTakingSpell(this, true);
3894
3897
3898 if (modOwner)
3899 modOwner->SetSpellModTakingSpell(this, false);
3900
3901 // Spell may be finished after target map check
3903 {
3904 SendInterrupted(0);
3905 finish(false);
3906 SetExecutedCurrently(false);
3907 return;
3908 }
3909
3910 if (modOwner)
3911 modOwner->SetSpellModTakingSpell(this, true);
3912
3914
3916
3917 if (modOwner)
3918 modOwner->SetSpellModTakingSpell(this, false);
3919
3920 // traded items have trade slot instead of guid in m_itemTargetGUID
3921 // set to real guid to be sent later to the client
3923
3924 if (m_caster->IsPlayer())
3925 {
3927 {
3930 }
3931
3933 }
3934
3936 {
3937 // Powers have to be taken before SendSpellGo
3938 TakePower();
3939 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3940 }
3941 else if (Item* targetItem = m_targets.GetItemTarget())
3942 {
3944 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3945 TakeReagents();
3946 }
3947
3949
3950 // CAST SPELL
3951 if (modOwner)
3952 modOwner->SetSpellModTakingSpell(this, true);
3953
3955
3957
3958 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3959 SendSpellGo();
3960
3961 if (modOwner)
3962 modOwner->SetSpellModTakingSpell(this, false);
3963
3964 if (m_originalCaster)
3965 {
3966 // Handle procs on cast
3967 uint32 procAttacker = m_procAttacker;
3968 if (!procAttacker)
3969 {
3970 bool IsPositive = m_spellInfo->IsPositive();
3972 {
3974 }
3975 else
3976 {
3978 }
3979 }
3980
3981 uint32 procEx = PROC_EX_NORMAL_HIT;
3982
3983 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3984 {
3985 if (ihit->missCondition != SPELL_MISS_NONE)
3986 {
3987 continue;
3988 }
3989
3990 if (!ihit->crit)
3991 {
3992 continue;
3993 }
3994
3995 procEx |= PROC_EX_CRITICAL_HIT;
3996 break;
3997 }
3998
4001 }
4002
4003 if (modOwner)
4004 modOwner->SetSpellModTakingSpell(this, true);
4005
4007 if (resetAttackTimers)
4008 {
4010 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4011 {
4012 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4013 {
4014 resetAttackTimers = false;
4015 break;
4016 }
4017 }
4018 }
4019
4020 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4021 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4022 {
4023 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4024 // in case delayed spell remove item at cast delay start
4025 TakeCastItem();
4026
4027 // Okay, maps created, now prepare flags
4028 m_immediateHandled = false;
4030 SetDelayStart(0);
4031
4034
4035 // remove all applied mods at this point
4036 // dont allow user to use them twice in case spell did not reach current target
4037 if (modOwner)
4038 modOwner->RemoveSpellMods(this);
4039
4040 // Xinef: why do we keep focus after spell is sent to air?
4041 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4042 // Xinef: we get focused to it out of nowhere...
4043 if (Creature* creatureCaster = m_caster->ToCreature())
4044 creatureCaster->ReleaseFocus(this);
4045 }
4046 else
4047 {
4048 // Immediate spell, no big deal
4050 }
4051
4052 if (resetAttackTimers)
4053 {
4054 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4055 {
4056 resetAttackTimers = false;
4057 }
4058
4059 if (resetAttackTimers)
4060 {
4062
4064 {
4066 }
4067
4069 }
4070 }
4071
4073
4074 if (modOwner)
4075 modOwner->SetSpellModTakingSpell(this, false);
4076
4077 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4078 {
4079 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4080 if (*i < 0)
4082 else
4084 }
4085
4086 // Interrupt Spell casting
4087 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4089 if (Unit* target = m_targets.GetUnitTarget())
4090 if (target->IsCreature())
4091 m_caster->CastSpell(target, 32747, true);
4092
4093 // xinef: start combat at cast for delayed spells, only for explicit target
4094 if (Unit* target = m_targets.GetUnitTarget())
4097 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4098
4099 if (m_caster->IsPlayer())
4102
4103 SetExecutedCurrently(false);
4104}
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:141
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ CHEAT_COOLDOWN
Definition: Player.h:1001
@ UNIT_STATE_CASTING
Definition: UnitDefines.h:164
#define sScriptMgr
Definition: ScriptMgr.h:709
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:143
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:473
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:419
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1545
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1519
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:112
bool IsCreature() const
Definition: Object.h:201
Creature * ToCreature()
Definition: Object.h:202
Definition: Pet.h:41
Definition: Player.h:1064
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2127
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:10034
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13869
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:9966
Pet * GetPet() const
Definition: Player.cpp:8863
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1178
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9014
TradeData * GetTradeData() const
Definition: Player.h:1368
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3503
Definition: TradeData.h:36
Definition: Unit.h:630
void ClearUnitState(uint32 f)
Definition: Unit.h:740
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1310
Unit * GetCharm() const
Definition: Unit.cpp:10611
Player * GetSpellModOwner() const
Definition: Unit.cpp:16516
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13645
bool haveOffhandWeapon() const
Definition: Unit.cpp:522
bool IsPet() const
Definition: Unit.h:754
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4064
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1154
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4874
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:6332
bool HasUnitState(const uint32 f) const
Definition: Unit.h:739
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10186
bool IsControlledByPlayer() const
Definition: Unit.h:1171
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20435
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:643
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:312
void UpdateTradeSlotItem()
Definition: Spell.cpp:349
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:317
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Definition: Spell.cpp:233
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:575
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8535
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8741
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition: Spell.h:553
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:772
void handle_immediate()
Definition: Spell.cpp:4106
void SendSpellGo()
Definition: Spell.cpp:4788
void TakeReagents()
Definition: Spell.cpp:5522
void SetExecutedCurrently(bool yes)
Definition: Spell.h:561
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5165
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8567
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8522
void cancel(bool bySelf=false)
Definition: Spell.cpp:3711
void SendSpellCooldown()
Definition: Spell.cpp:4346
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8509
void HandleLaunchPhase()
Definition: Spell.cpp:8222
bool UpdatePointers()
Definition: Spell.cpp:7852
void SetDelayStart(uint64 m_time)
Definition: Spell.h:563
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:682
void SelectSpellTargets()
Definition: Spell.cpp:816
void TakePower()
Definition: Spell.cpp:5306
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5644
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4660
uint64 GetDelayMoment() const
Definition: Spell.h:564
void TakeCastItem()
Definition: Spell.cpp:5243
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8066
void finish(bool ok=true)
Definition: Spell.cpp:4473
float Speed
Definition: SpellInfo.h:370
bool IsChanneled() const
Definition: SpellInfo.cpp:1255
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2351
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:892

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), Unit::HasUnitState(), Unit::haveOffhandWeapon(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4272{
4273 // Take for real after all targets are processed
4275 {
4277 }
4278
4279 // Real add combo points from effects
4281 {
4282 // remove Premed-like effects unless they were caused by ourselves
4283 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4285 {
4287 }
4288
4290 }
4291
4293 {
4295 }
4296
4299 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4300 {
4301 // Xinef: Properly clear infinite cooldowns in some cases
4302 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4305 }
4306
4307 // Handle procs on finish
4308 if (m_originalCaster)
4309 {
4310 uint32 procAttacker = m_procAttacker;
4311 if (!procAttacker)
4312 {
4313 bool IsPositive = m_spellInfo->IsPositive();
4315 {
4317 }
4318 else
4319 {
4321 }
4322 }
4323
4324 uint32 procEx = PROC_EX_NORMAL_HIT;
4325 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4326 {
4327 if (ihit->missCondition != SPELL_MISS_NONE)
4328 {
4329 continue;
4330 }
4331
4332 if (!ihit->crit)
4333 {
4334 continue;
4335 }
4336
4337 procEx |= PROC_EX_CRITICAL_HIT;
4338 break;
4339 }
4340
4343 }
4344}
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:797
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11062
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:914
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10561
void ClearComboPoints()
Definition: Unit.cpp:16803
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16777
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5064
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8056
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1211

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4244{
4245 m_spellAura = nullptr;
4246 // initialize Diminishing Returns Data
4249
4250 // handle some immediate features of the spell here
4252
4254
4255 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4256 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4257 {
4258 // don't do anything for empty effect
4259 if (!m_spellInfo->Effects[j].IsEffect())
4260 continue;
4261
4262 // call effect handlers to handle destination hit
4263 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4264 }
4265
4266 // process items
4267 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4268 DoAllEffectOnTarget(&(*ihit));
4269}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5571
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5618
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:699
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2610
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
531 {
532 if (target != m_comboTarget)
533 {
534 m_comboTarget = target;
535 m_comboPointGain = amount;
536 }
537 else
538 {
539 m_comboPointGain += amount;
540 }
541 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2606{
2607 m_destTargets[effIndex] = dest;
2608}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2515{
2516 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2517 {
2518 if (!m_spellInfo->Effects[effIndex].IsEffect())
2519 effectMask &= ~(1 << effIndex);
2520 else
2521 {
2522 switch (m_spellInfo->Effects[effIndex].Effect)
2523 {
2527 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2528 effectMask &= ~(1 << effIndex);
2529 break;
2530 default:
2531 break;
2532 }
2533 }
2534 }
2535
2536 if (!effectMask)
2537 return;
2538
2539 ObjectGuid targetGUID = go->GetGUID();
2540
2541 // Lookup target in already in list
2542 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2543 {
2544 if (targetGUID == ihit->targetGUID) // Found in list
2545 {
2546 ihit->effectMask |= effectMask; // Add only effect mask
2547 return;
2548 }
2549 }
2550
2551 // This is new target calculate data for him
2552
2553 GOTargetInfo target;
2554 target.targetGUID = targetGUID;
2555 target.effectMask = effectMask;
2556 target.processed = false; // Effects not apply on target
2557
2558 // Spell have speed - need calculate incoming time
2559 if (m_spellInfo->Speed > 0.0f)
2560 {
2561 // calculate spell incoming interval
2562 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2563 if (dist < 5.0f)
2564 dist = 5.0f;
2565 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2566 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2567 m_delayMoment = target.timeDelay;
2568 }
2569 else
2570 target.timeDelay = 0LL;
2571
2572 // Add target to list
2573 m_UniqueGOTargetInfo.push_back(target);
2574}
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1593
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:866
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:867
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:865
std::uint64_t uint64
Definition: Define.h:106
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1245
Definition: ObjectGuid.h:118
uint64 m_delayMoment
Definition: Spell.h:639
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:692

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2577{
2578 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2579 if (!m_spellInfo->Effects[effIndex].IsEffect())
2580 effectMask &= ~(1 << effIndex);
2581
2582 // no effects left
2583 if (!effectMask)
2584 return;
2585
2586 // Lookup target in already in list
2587 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2588 {
2589 if (item == ihit->item) // Found in list
2590 {
2591 ihit->effectMask |= effectMask; // Add only effect mask
2592 return;
2593 }
2594 }
2595
2596 // This is new target add data
2597
2598 ItemTargetInfo target;
2599 target.item = item;
2600 target.effectMask = effectMask;
2601
2602 m_UniqueItemInfo.push_back(target);
2603}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2382{
2383 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2384 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2385 effectMask &= ~(1 << effIndex);
2386
2387 // no effects left
2388 if (!effectMask)
2389 return;
2390
2391 if (checkIfValid)
2392 {
2393 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2394 if (res != SPELL_CAST_OK)
2395 return;
2396 }
2397
2398 // Check for effect immune skip if immuned
2399 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2400 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2401 effectMask &= ~(1 << effIndex);
2402
2403 ObjectGuid targetGUID = target->GetGUID();
2404
2405 // Lookup target in already in list
2406 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2407 {
2408 if (targetGUID == ihit->targetGUID) // Found in list
2409 {
2410 ihit->effectMask |= effectMask; // Immune effects removed from mask
2411 ihit->scaleAura = false;
2412 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2413 {
2414 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2415 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2416 ihit->scaleAura = true;
2417 }
2418
2419 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2420 return;
2421 }
2422 }
2423
2424 // This is new target calculate data for him
2425
2426 // Get spell hit result on target
2427 TargetInfo targetInfo;
2428 targetInfo.targetGUID = targetGUID; // Store target GUID
2429 targetInfo.effectMask = effectMask; // Store all effects not immune
2430 targetInfo.processed = false; // Effects not apply on target
2431 targetInfo.alive = target->IsAlive();
2432 targetInfo.damage = 0;
2433 targetInfo.crit = false;
2434 targetInfo.scaleAura = false;
2435 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2436 {
2437 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2438 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2439 targetInfo.scaleAura = true;
2440 }
2441
2442 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2443
2444 // Calculate hit result
2445 if (m_originalCaster)
2446 {
2447 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2448 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2449 {
2450 targetInfo.missCondition = SPELL_MISS_NONE;
2451 }
2452 }
2453 else
2454 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2455
2456 // Spell have speed - need calculate incoming time
2457 // Incoming time is zero for self casts. At least I think so.
2458 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2459 {
2460 // calculate spell incoming interval
2462 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2463
2464 if (dist < 5.0f)
2465 dist = 5.0f;
2466 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2467
2468 // Calculate minimum incoming time
2469 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2470 m_delayMoment = targetInfo.timeDelay;
2471 }
2472 else
2473 targetInfo.timeDelay = 0LL;
2474
2475 // If target reflect spell back to caster
2476 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2477 {
2478 // Calculate reflected spell result on caster
2480
2481 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2482 targetInfo.reflectResult = SPELL_MISS_PARRY;
2483
2484 // Increase time interval for reflected spells by 1.5
2486 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2487
2489
2490 // HACK: workaround check for succubus seduction case
2492 if (m_caster->IsPet())
2493 {
2494 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2495 switch (ci->family)
2496 {
2498 {
2499 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2500 cancel();
2501 }
2502 break;
2503 return;
2504 }
2505 }
2506 }
2507 else
2508 targetInfo.reflectResult = SPELL_MISS_NONE;
2509
2510 // Add target to list
2511 m_UniqueTargetInfo.push_back(targetInfo);
2512}
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:82
#define sObjectMgr
Definition: ObjectMgr.h:1623
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2664
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1523
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1526
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1525
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1530
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:159
Definition: CreatureData.h:189
uint32 family
Definition: CreatureData.h:220
float GetPositionZ() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
bool IsAlive() const
Definition: Unit.h:1151
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3437
EventProcessor m_Events
Definition: Unit.h:1437
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:12946
uint8 GetLevel() const
Definition: Unit.h:759
Definition: Spell.h:254
bool processed
Definition: Spell.h:260
int32 damage
Definition: Spell.h:264
SpellMissInfo missCondition
Definition: Spell.h:257
bool scaleAura
Definition: Spell.h:263
bool crit
Definition: Spell.h:262
uint64 timeDelay
Definition: Spell.h:256
ObjectGuid targetGUID
Definition: Spell.h:255
SpellMissInfo reflectResult
Definition: Spell.h:258
bool alive
Definition: Spell.h:261
uint8 effectMask
Definition: Spell.h:259
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7914
Definition: Spell.h:846
Definition: SpellInfo.h:316
uint32 SpellLevel
Definition: SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2500
uint32 SpellIconID
Definition: SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1758

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, Unit::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
897{
898 if (m_targets.HasDst())
899 {
900 if (m_targets.HasTraj())
901 {
902 float speed = m_targets.GetSpeedXY();
903 if (speed > 0.0f)
904 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
905 }
906 else if (m_spellInfo->Speed > 0.0f)
907 {
908 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
909 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
910 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
911 }
912 }
913
914 return 0;
915}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:178
bool HasTraj() const
Definition: Spell.h:166
bool HasDst() const
Definition: Spell.h:165
float GetSpeedXY() const
Definition: Spell.h:174
float GetDist2d() const
Definition: Spell.h:173
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:402

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1158{
1159 if (m_spellInfo->Effects[i].MiscValue)
1160 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1161 else if (m_spellInfo->Effects[i].MiscValueB)
1162 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1163 else
1164 speedZ = 10.0f;
1165 speedXY = dist * 10.0f / speedZ;
1166}

References SpellInfo::Effects, and m_spellInfo.

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14789
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:213

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8536{
8537 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8538 {
8539 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8540 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8541 for (; hookItr != hookItrEnd; ++hookItr)
8542 (*hookItr).Call(*scritr);
8543
8544 (*scritr)->_FinishScriptCall();
8545 }
8546}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8648{
8649 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8650 {
8651 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8652 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8653 for (; hookItr != hookItrEnd; ++hookItr)
8654 (*hookItr).Call(*scritr);
8655
8656 (*scritr)->_FinishScriptCall();
8657 }
8658}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8510{
8511 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8512 {
8513 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8514 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8515 for (; hookItr != hookItrEnd; ++hookItr)
8516 (*hookItr).Call(*scritr);
8517
8518 (*scritr)->_FinishScriptCall();
8519 }
8520}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8622{
8623 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8624 {
8625 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8626 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8627 for (; hookItr != hookItrEnd; ++hookItr)
8628 (*hookItr).Call(*scritr, missInfo);
8629
8630 (*scritr)->_FinishScriptCall();
8631 }
8632}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8549{
8551 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8552 {
8553 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8554 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8555 for (; hookItr != hookItrEnd; ++hookItr)
8556 {
8557 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8558 if (retVal == SPELL_CAST_OK)
8559 retVal = tempResult;
8560 }
8561
8562 (*scritr)->_FinishScriptCall();
8563 }
8564 return retVal;
8565}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8689{
8690 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8691 {
8692 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8693 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8694 for (; hookItr != hookItrEnd; ++hookItr)
8695 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8696 hookItr->Call(*scritr, target);
8697
8698 (*scritr)->_FinishScriptCall();
8699 }
8700}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8574{
8575 // execute script effect handler hooks and check if effects was prevented
8576 bool preventDefault = false;
8577 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8578 {
8579 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8580 SpellScriptHookType hookType;
8581 switch (mode)
8582 {
8584 effItr = (*scritr)->OnEffectLaunch.begin();
8585 effEndItr = (*scritr)->OnEffectLaunch.end();
8587 break;
8589 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8590 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8592 break;
8594 effItr = (*scritr)->OnEffectHit.begin();
8595 effEndItr = (*scritr)->OnEffectHit.end();
8597 break;
8599 effItr = (*scritr)->OnEffectHitTarget.begin();
8600 effEndItr = (*scritr)->OnEffectHitTarget.end();
8602 break;
8603 default:
8604 ABORT();
8605 return false;
8606 }
8607 (*scritr)->_PrepareScriptCall(hookType);
8608 for (; effItr != effEndItr; ++effItr)
8609 // effect execution can be prevented
8610 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8611 (*effItr).Call(*scritr, effIndex);
8612
8613 if (!preventDefault)
8614 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8615
8616 (*scritr)->_FinishScriptCall();
8617 }
8618 return preventDefault;
8619}
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:234
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:236
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162
#define ABORT
Definition: Errors.h:76

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8661{
8662 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8663 {
8664 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8665 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8666 for (; hookItr != hookItrEnd; ++hookItr)
8667 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8668 hookItr->Call(*scritr, targets);
8669
8670 (*scritr)->_FinishScriptCall();
8671 }
8672}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8675{
8676 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8677 {
8678 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8679 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8680 for (; hookItr != hookItrEnd; ++hookItr)
8681 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8682 hookItr->Call(*scritr, target);
8683
8684 (*scritr)->_FinishScriptCall();
8685 }
8686}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8523{
8524 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8525 {
8526 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8527 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8528 for (; hookItr != hookItrEnd; ++hookItr)
8529 (*hookItr).Call(*scritr);
8530
8531 (*scritr)->_FinishScriptCall();
8532 }
8533}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8635{
8636 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8637 {
8638 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8639 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8640 for (; hookItr != hookItrEnd; ++hookItr)
8641 (*hookItr).Call(*scritr);
8642
8643 (*scritr)->_FinishScriptCall();
8644 }
8645}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
6999{
7000 ObjectGuid targetguid = target->GetGUID();
7001
7002 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7003 {
7005 {
7006 if (m_spellInfo->StackAmount <= 1)
7007 {
7008 if (target->HasAuraEffect(m_spellInfo->Id, j))
7009 return false;
7010 }
7011 else
7012 {
7013 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7014 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7015 return false;
7016 }
7017 }
7018 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7019 {
7020 if (target->HasAuraEffect(m_spellInfo->Id, j))
7021 return false;
7022 }
7023 }
7024
7025 SpellCastResult result = CheckPetCast(target);
7026
7027 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7028 {
7030 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7031 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7032 if (ihit->targetGUID == targetguid)
7033 return true;
7034 }
7035 return false; //target invalid
7036}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5448
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5622
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6805
uint32 StackAmount
Definition: SpellInfo.h:371

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3712{
3714 return;
3715
3716 uint32 oldState = m_spellState;
3718
3719 m_autoRepeat = false;
3720 switch (oldState)
3721 {
3725
3726 if (m_caster->IsPlayer())
3727 {
3729 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3730 }
3731 [[fallthrough]];
3734 break;
3736 if (!bySelf)
3737 {
3738 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3739 if ((*ihit).missCondition == SPELL_MISS_NONE)
3740 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3741 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3742
3745
3748 }
3749
3751 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3752
3753 // spell is canceled-take mods and clear list
3754 if (Player* player = m_caster->GetSpellModOwner())
3755 player->RemoveSpellMods(this);
3756
3757 m_appliedMods.clear();
3758 break;
3759 default:
3760 break;
3761 }
3762
3764 if (m_selfContainer && *m_selfContainer == this)
3765 *m_selfContainer = nullptr;
3766
3767 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3769 {
3771 }
3772
3773 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3775
3776 //set state back so finish will be processed
3777 m_spellState = oldState;
3778
3779 finish(false);
3780}
@ SPELL_STATE_PREPARING
Definition: Spell.h:224
@ SPELL_STATE_CASTING
Definition: Spell.h:225
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:850
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:989
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:532
bool NeedSendSpectatorData() const
Definition: Player.cpp:15351
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6151
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6095
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5182
void CancelGlobalCooldown()
Definition: Spell.cpp:8876
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:559
UsedSpellMods m_appliedMods
Definition: Spell.h:545

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8877{
8879 return;
8880
8881 // Cancel global cooldown when interrupting current cast
8883 return;
8884
8885 // Only players or controlled units have global cooldown
8886 if (m_caster->GetCharmInfo())
8888 else if (m_caster->IsPlayer())
8890}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1782
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: CharmInfo.cpp:415
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: CharmInfo.h:158
CharmInfo * GetCharmInfo()
Definition: Unit.h:1226
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1404
uint32 StartRecoveryTime
Definition: SpellInfo.h:351

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8726{
8727 // Relentless strikes, proc only from first effect
8728 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8729 return effMask & (1 << EFFECT_0);
8730
8731 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8732 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8733 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8734 {
8735 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8736 return true;
8737 }
8738 return effMask;
8739}
@ EFFECT_0
Definition: SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:531

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8350{
8351 if (!lockId) // possible case for GO and maybe for items.
8352 return SPELL_CAST_OK;
8353
8354 // Get LockInfo
8355 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8356
8357 if (!lockInfo)
8359
8360 bool reqKey = false; // some locks not have reqs
8361
8362 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8363 {
8364 switch (lockInfo->Type[j])
8365 {
8366 // check key item (many fit cases can be)
8367 case LOCK_KEY_ITEM:
8368 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8369 return SPELL_CAST_OK;
8370 reqKey = true;
8371 break;
8372 // check key skill (only single first fit case can be)
8373 case LOCK_KEY_SKILL:
8374 {
8375 reqKey = true;
8376
8377 // wrong locktype, skip
8378 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8379 continue;
8380
8381 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8382
8383 if (skillId != SKILL_NONE)
8384 {
8385 reqSkillValue = lockInfo->Skill[j];
8386
8387 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8388 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8389 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8390
8391 // skill bonus provided by casting spell (mostly item spells)
8392 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8393 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8395 {
8396 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8397 }
8398
8399 if (skillValue < reqSkillValue)
8401 }
8402
8403 return SPELL_CAST_OK;
8404 }
8405 case LOCK_KEY_SPELL:
8406 {
8407 if (m_spellInfo->Id == lockInfo->Index[j])
8408 {
8409 return SPELL_CAST_OK;
8410 }
8411 reqKey = true;
8412 break;
8413 }
8414 }
8415 }
8416
8417 if (reqKey)
8419
8420 return SPELL_CAST_OK;
8421}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1305
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1430
LockType
Definition: SharedDefines.h:2591
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2585
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2586
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2587
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:961
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:998
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:3020
@ SKILL_NONE
Definition: SharedDefines.h:2864
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2975
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5394
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1004
Definition: DBCStructure.h:1308
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1311
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1312

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3783{
3784 Player* modOwner = m_caster->GetSpellModOwner();
3785 Spell* lastMod = nullptr;
3786 if (modOwner)
3787 {
3788 lastMod = modOwner->m_spellModTakingSpell;
3789 if (lastMod)
3790 modOwner->SetSpellModTakingSpell(lastMod, false);
3791 }
3792
3793 _cast(skipCheck);
3794
3795 if (lastMod)
3796 modOwner->SetSpellModTakingSpell(lastMod, true);
3797}
Spell * m_spellModTakingSpell
Definition: Player.h:2529
Definition: Spell.h:284
void _cast(bool skipCheck)
Definition: Spell.cpp:3799

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5645{
5646 // check death state
5649
5650 // Spectator check
5651 if (m_caster->IsPlayer())
5652 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5653 return SPELL_FAILED_NOT_HERE;
5654
5656
5657 sScriptMgr->OnSpellCheckCast(this, strict, res);
5658
5659 if (res != SPELL_CAST_OK)
5660 return res;
5661
5662 // check cooldowns to prevent cheating
5664 {
5665 if (m_caster->IsPlayer())
5666 {
5667 //can cast triggered (by aura only?) spells while have this flag
5670
5672 {
5675 else
5677 }
5678
5679 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5682 }
5685 }
5686
5688 {
5691 }
5692
5693 // Check global cooldown
5696
5697 // only triggered spells can be processed an ended battleground
5698 if (!IsTriggered() && m_caster->IsPlayer())
5700 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5702
5703 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5704 {
5706 !m_caster->IsOutdoors())
5708
5712 }
5713
5714 // only check at first call, Stealth auras are already removed at second call
5715 // for now, ignore triggered spells
5717 {
5718 bool checkForm = true;
5719 // Ignore form req aura
5721 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5722 {
5723 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5724 continue;
5725 checkForm = false;
5726 break;
5727 }
5728 if (checkForm)
5729 {
5730 // Cannot be used in this stance/form
5732 if (shapeError != SPELL_CAST_OK)
5733 return shapeError;
5734
5737 }
5738 }
5739
5741 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5742 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5744
5745 bool reqCombat = true;
5747 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5748 {
5749 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5750 {
5751 m_needComboPoints = false;
5752 if ((*j)->GetMiscValue() == 1)
5753 {
5754 reqCombat = false;
5755 break;
5756 }
5757 }
5758 }
5759
5760 // caster state requirements
5761 // not for triggered spells (needed by execute)
5763 {
5768
5769 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5774
5775 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5777 }
5778
5779 // Xinef: exploit protection
5781 {
5782 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5783 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5784 if (instanceScript->IsEncounterInProgress())
5785 {
5786 if (Group* group = m_caster->ToPlayer()->GetGroup())
5787 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5788 if (Player* member = itr->GetSource())
5789 if (member->IsInMap(m_caster))
5790 if (Unit* victim = member->GetVictim())
5791 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5792 {
5793 m_caster->CombatStart(victim);
5794 victim->AddThreat(m_caster, 1.0f);
5795 break;
5796 }
5798 }
5799 }
5800
5801 // cancel autorepeat spells if cast start when moving
5802 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5803 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5804 {
5805 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5808 return SPELL_FAILED_MOVING;
5809 }
5810
5811 Vehicle* vehicle = m_caster->GetVehicle();
5813 {
5814 uint16 checkMask = 0;
5815 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5816 {
5817 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5819 {
5820 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5821 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5822 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5823 break;
5824 }
5825 }
5826
5829
5830 if (!checkMask)
5831 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5832
5833 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5834 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5836 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5838 }
5839
5840 // check spell cast conditions from database
5841 {
5844 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5845 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5846 {
5847 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5848 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5849 {
5853 }
5854 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5857 }
5858 }
5859
5860 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5861 // those spells may have incorrect target entries or not filled at all (for example 15332)
5862 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5863 // also, such casts shouldn't be sent to client
5864 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5866 {
5867 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5868 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5870 {
5872 if (castResult != SPELL_CAST_OK)
5873 return castResult;
5874 }
5875 }
5876
5877 if (Unit* target = m_targets.GetUnitTarget())
5878 {
5879 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5880 if (castResult != SPELL_CAST_OK)
5881 return castResult;
5882
5883 if (target != m_caster)
5884 {
5885 // Must be behind the target
5886 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5888
5889 // Target must be facing you
5890 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5892
5895 {
5896 bool castedByGameobject = false;
5897 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5899 {
5900 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5901 }
5902 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5903 {
5904 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5905 {
5906 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5907 }
5908 }
5909
5910 if (castedByGameobject)
5911 {
5912 // If spell casted by gameobject then ignore M2 models
5913 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5914 }
5915
5917 {
5919 }
5920 }
5921 }
5922 }
5923
5924 // Check for line of sight for spells with dest
5925 if (m_targets.HasDst())
5926 {
5927 float x, y, z;
5928 m_targets.GetDstPos()->GetPosition(x, y, z);
5929
5932 {
5933 bool castedByGameobject = false;
5934 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5936 {
5937 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5938 }
5939 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5940 {
5941 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5942 {
5943 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5944 }
5945 }
5946
5947 if (castedByGameobject)
5948 {
5949 // If spell casted by gameobject then ignore M2 models
5950 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5951 }
5952
5954 {
5956 }
5957 }
5958 }
5959
5960 // check pet presence
5961 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5962 {
5963 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5964 {
5966 {
5967 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5969 else
5970 return SPELL_FAILED_NO_PET;
5971 }
5972 break;
5973 }
5974 }
5975 // Spell casted only on battleground
5977 if (!m_caster->ToPlayer()->InBattleground())
5979
5980 // do not allow spells to be cast in arenas
5981 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5982 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5985 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5986 if (mapEntry->IsBattleArena())
5988
5989 // zone check
5991 {
5992 uint32 zone, area;
5993 m_caster->GetZoneAndAreaId(zone, area);
5994
5996 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
5997 if (locRes != SPELL_CAST_OK)
5998 return locRes;
5999 }
6000
6001 // not let players cast spells at mount (and let do it to creatures)
6004 {
6005 if (m_caster->IsInFlight())
6007 else
6009 }
6010
6011 SpellCastResult castResult = SPELL_CAST_OK;
6012
6013 // always (except passive spells) check items (focus object can be required for any type casts)
6014 if (!m_spellInfo->IsPassive())
6015 {
6016 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6017 castResult = CheckSpellFocus();
6018 if (castResult != SPELL_CAST_OK)
6019 return castResult;
6020
6021 castResult = CheckItems();
6022 if (castResult != SPELL_CAST_OK)
6023 return castResult;
6024 }
6025
6026 // Triggered spells also have range check
6028 castResult = CheckRange(strict);
6029 if (castResult != SPELL_CAST_OK)
6030 return castResult;
6031
6033 {
6034 castResult = CheckPower();
6035 if (castResult != SPELL_CAST_OK)
6036 return castResult;
6037 }
6038
6040 {
6041 return SPELL_CAST_OK;
6042 }
6043
6044 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6046 {
6048 if (castResult != SPELL_CAST_OK)
6049 return castResult;
6050
6051 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6053 {
6055 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6056 if (itr->type == m_spellInfo->Mechanic)
6058 }
6059 }
6060
6061 // script hook
6062 castResult = CallScriptCheckCastHandlers();
6063 if (castResult != SPELL_CAST_OK)
6064 return castResult;
6065
6066 bool hasDispellableAura = false;
6067 bool hasNonDispelEffect = false;
6068 uint32 dispelMask = 0;
6069 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6070 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6071 {
6073 {
6074 hasDispellableAura = true;
6075 break;
6076 }
6077
6078 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6079 }
6080 else if (m_spellInfo->Effects[i].IsEffect())
6081 {
6082 hasNonDispelEffect = true;
6083 break;
6084 }
6085
6086 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6087 {
6088 if (Unit* target = m_targets.GetUnitTarget())
6089 {
6090 // Xinef: do not allow to cast on hostile targets in sanctuary
6091 if (!m_caster->IsFriendlyTo(target))
6092 {
6093 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6094 {
6095 // Xinef: fix for duels
6096 Player* player = m_caster->ToPlayer();
6097 if (!player || !player->duel || target != player->duel->Opponent)
6099 }
6100 }
6101
6102 DispelChargesList dispelList;
6103 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6104
6105 if (dispelList.empty())
6107 }
6108 }
6109
6110 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6111 {
6112 // for effects of spells that have only one target
6113 switch (m_spellInfo->Effects[i].Effect)
6114 {
6116 {
6117 if (!m_caster->IsPlayer())
6119
6120 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6121 break;
6122
6123 Pet* pet = m_caster->ToPlayer()->GetPet();
6124
6125 if (!pet)
6126 return SPELL_FAILED_NO_PET;
6127
6128 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6129
6130 if (!learn_spellproto)
6132
6133 if (m_spellInfo->SpellLevel > pet->GetLevel())
6134 return SPELL_FAILED_LOWLEVEL;
6135
6136 break;
6137 }
6139 {
6140 // check target only for unit target case
6142 {
6143 if (!m_caster->IsPlayer())
6145
6146 Pet* pet = unitTarget->ToPet();
6147 if (!pet || pet->GetOwner() != m_caster)
6149
6150 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6151
6152 if (!learn_spellproto)
6154
6155 if (m_spellInfo->SpellLevel > pet->GetLevel())
6156 return SPELL_FAILED_LOWLEVEL;
6157 }
6158 break;
6159 }
6161 {
6162 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6163 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6164 if (m_caster->HasAura(gp->SpellId))
6166 break;
6167 }
6169 {
6170 if (!m_caster->IsPlayer())
6172
6173 Item* foodItem = m_targets.GetItemTarget();
6174 if (!foodItem)
6176
6177 Pet* pet = m_caster->ToPlayer()->GetPet();
6178
6179 if (!pet)
6180 return SPELL_FAILED_NO_PET;
6181
6182 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6184
6185 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6187
6188 if (m_caster->IsInCombat() || pet->IsInCombat())
6190
6191 break;
6192 }
6195 {
6196 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6197 if (m_caster->IsPlayer())
6198 if (Unit* target = m_targets.GetUnitTarget())
6199 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6201 break;
6202 }
6204 {
6206 {
6208 }
6209
6211 {
6212 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6213 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6215 }
6217 {
6218 // Exception for Master's Call
6219 if (m_spellInfo->Id != 54216)
6220 {
6221 return SPELL_FAILED_ROOTED;
6222 }
6223 }
6224 if (m_caster->IsPlayer())
6225 if (Unit* target = m_targets.GetUnitTarget())
6226 if (!target->IsAlive())
6228 // Xinef: Pass only explicit unit target spells
6229 // pussywizard:
6231 {
6232 Unit* target = m_targets.GetUnitTarget();
6233 if (!target)
6235
6236 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6237 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6239
6240 float objSize = target->GetCombatReach();
6241 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6242
6243 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6244 m_preGeneratedPath->SetPathLengthLimit(range);
6245
6246 // first try with raycast, if it fails fall back to normal path
6247 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6248 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6249 return SPELL_FAILED_NOPATH;
6250 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6251 return SPELL_FAILED_NOPATH;
6252 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6253 return SPELL_FAILED_NOPATH;
6254
6255 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6256 }
6257 if (Player* player = m_caster->ToPlayer())
6258 player->SetCanTeleport(true);
6259 break;
6260 }
6262 {
6265
6268
6269 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6270 if (!creature->IsCritter() && !creature->loot.isLooted())
6272
6273 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6274
6275 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6276 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6277 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6278 if (ReqValue > skillValue)
6280
6281 break;
6282 }
6284 {
6285 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6286 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6287 break;
6288
6289 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6290 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6291 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6293
6294 Item* pTempItem = nullptr;
6296 {
6297 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6298 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6299 }
6302
6303 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6304 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6306 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6308
6309 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6310 if (GameObject* go = m_targets.GetGOTarget())
6311 {
6312 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6313 {
6315 }
6316 }
6317 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6319 {
6320 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6321 {
6322 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6324 }
6325 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6328 }
6329
6330 // get the lock entry
6331 uint32 lockId = 0;
6332 if (GameObject* go = m_targets.GetGOTarget())
6333 {
6334 lockId = go->GetGOInfo()->GetLockId();
6335 if (!lockId)
6337 }
6338 else if (Item* itm = m_targets.GetItemTarget())
6339 lockId = itm->GetTemplate()->LockID;
6340
6341 SkillType skillId = SKILL_NONE;
6342 int32 reqSkillValue = 0;
6343 int32 skillValue = 0;
6344
6345 // check lock compatibility
6346 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6347 if (res != SPELL_CAST_OK)
6348 return res;
6349
6350 // chance for fail at lockpicking attempt
6351 // second check prevent fail at rechecks
6352 // herbalism and mining cannot fail as of patch 3.1.0
6353 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6354 {
6355 // chance for failure in orange lockpick
6356 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6357 {
6359 }
6360 }
6361 break;
6362 }
6364 {
6365 Unit* unitCaster = m_caster->ToUnit();
6366 if (!unitCaster)
6367 {
6369 }
6370
6371 Creature* pet = unitCaster->GetGuardianPet();
6372 if (pet)
6373 {
6374 if (pet->IsAlive())
6375 {
6377 }
6378 }
6379 else if (Player* playerCaster = m_caster->ToPlayer())
6380 {
6381 PetStable& petStable = playerCaster->GetOrInitPetStable();
6382 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6383 {
6384 return SPELL_FAILED_NO_PET;
6385 }
6386 }
6387
6388 break;
6389 }
6390 // This is generic summon effect
6392 {
6393 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6394 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6395 break;
6396 switch (SummonProperties->Category)
6397 {
6399 if (m_caster->GetPetGUID())
6401 [[fallthrough]];
6403 if (m_caster->GetCharmGUID())
6405 break;
6406 }
6407 break;
6408 }
6410 {
6412 {
6417 }
6418 break;
6419 }
6421 {
6422 Unit* unitCaster = m_caster->ToUnit();
6423 if (!unitCaster)
6425
6427 {
6428 if (m_caster->GetPetGUID())
6430 if (m_caster->GetCharmGUID())
6432 }
6433
6435 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6436 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6437
6438 Player* playerCaster = unitCaster->ToPlayer();
6439 if (playerCaster && playerCaster->GetPetStable())
6440 {
6441 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6442 if (info.first)
6443 {
6444 if (info.first->Type == HUNTER_PET)
6445 {
6446 if (!info.first->Health)
6447 {
6448 playerCaster->SendTameFailure(PET_TAME_DEAD);
6450 }
6451
6452 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6453 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6454 {
6455 // if problem in exotic pet
6456 if (creatureInfo && creatureInfo->IsTameable(true))
6458 else
6460
6462 }
6463 }
6464 }
6465 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6466 {
6469 }
6470 }
6471 break;
6472 }
6474 {
6475 if (!m_caster->IsPlayer())
6477 if (!m_caster->GetTarget())
6479
6481 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6483
6484 // Xinef: Implement summon pending error
6485 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6487
6488 // check if our map is dungeon
6489 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6490 if (map->IsDungeon())
6491 {
6492 uint32 mapId = m_caster->GetMap()->GetId();
6493 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6494 /*if (map->IsRaid())
6495 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6496 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6497 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6498
6499 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6500 if (!instance)
6502 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6504 }
6505 break;
6506 }
6507 // RETURN HERE
6509 {
6510 if (!m_caster->IsPlayer())
6512
6513 Player* playerCaster = m_caster->ToPlayer();
6514 //
6515 if (!(playerCaster->GetTarget()))
6517
6519
6520 if (!target ||
6521 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6523
6524 // Xinef: Implement summon pending error
6525 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6527
6528 break;
6529 }
6530 case SPELL_EFFECT_LEAP:
6532 {
6533 //Do not allow to cast it before BG starts.
6534 if (m_caster->IsPlayer())
6535 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6536 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6538 break;
6539 }
6541 {
6544
6545 bool found = false;
6547 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6548 {
6549 if( itr->second->GetBase()->IsPassive() )
6550 continue;
6551
6552 if( !itr->second->IsPositive() )
6553 continue;
6554
6555 found = true;
6556 break;
6557 }
6558
6559 if( !found )
6561
6562 break;
6563 }
6565 {
6567 {
6568 if (m_caster->IsPlayer())
6569 return SPELL_FAILED_ROOTED;
6570 else
6572 }
6573 break;
6574 }
6575 // xinef: do not allow to use leaps while rooted
6576 case SPELL_EFFECT_JUMP:
6578 {
6580 return SPELL_FAILED_ROOTED;
6581 break;
6582 }
6584 if (!sScriptMgr->CanSelectSpecTalent(this))
6586 // can't change during already started arena/battleground
6587 if (m_caster->IsPlayer())
6588 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6589 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6591 break;
6592 default:
6593 break;
6594 }
6595 }
6596
6597 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6598 {
6599 switch (m_spellInfo->Effects[i].ApplyAuraName)
6600 {
6601 case SPELL_AURA_DUMMY:
6602 break;
6604 {
6605 if (!m_caster->IsPlayer())
6606 return SPELL_FAILED_NO_PET;
6607
6608 Pet* pet = m_caster->ToPlayer()->GetPet();
6609 if (!pet)
6610 return SPELL_FAILED_NO_PET;
6611
6612 if (pet->GetCharmerGUID())
6613 return SPELL_FAILED_CHARMED;
6614 break;
6615 }
6619 {
6620 if (m_caster->GetCharmerGUID())
6621 return SPELL_FAILED_CHARMED;
6622
6623 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6625 {
6626 if (m_caster->GetPetGUID())
6628
6629 if (m_caster->GetCharmGUID())
6631 }
6632 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6633 {
6634 if (m_caster->GetCharmGUID())
6636 }
6637
6638 if (Unit* target = m_targets.GetUnitTarget())
6639 {
6640 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6642
6643 if (target->IsMounted())
6645
6646 if (target->GetCharmerGUID())
6647 return SPELL_FAILED_CHARMED;
6648
6649 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6651
6652 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6654
6655 int32 damage = CalculateSpellDamage(i, target);
6656 if (damage && int32(target->GetLevel()) > damage)
6658 }
6659
6660 break;
6661 }
6662 case SPELL_AURA_MOUNTED:
6663 {
6664 // Disallow casting flying mounts in water
6667
6668 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6669 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6670 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6671 if (it)
6672 allowMount = it->AllowMount;
6673 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6675
6678
6679 // xinef: dont allow to cast mounts in specific transforms
6680 if (m_caster->getTransForm())
6681 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6682 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6683 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6685
6686 break;
6687 }
6689 {
6690 if (!m_targets.GetUnitTarget())
6692
6693 // can be casted at non-friendly unit or own pet/charm
6696
6697 break;
6698 }
6699 case SPELL_AURA_FLY:
6701 {
6702 // Xinef: added water check
6703 if (m_caster->IsInWater())
6705
6706 // not allow cast fly spells if not have req. skills (all spells is self target)
6707 // allow always ghost flight spells
6709 {
6710 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6711 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6712 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6713 return SPELL_FAILED_NOT_HERE;
6714 }
6715 break;
6716 }
6718 {
6719 if (m_spellInfo->Effects[i].IsTargetingArea())
6720 break;
6721
6722 if (!m_caster->IsPlayer() || m_CastItem)
6723 break;
6724
6725 if (!m_targets.GetUnitTarget())
6727
6730
6731 break;
6732 }
6733 case SPELL_AURA_HOVER:
6734 {
6736 {
6738 }
6739 break;
6740 }
6742 {
6743 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6744 {
6746 }
6747 break;
6748 }
6749 default:
6750 break;
6751 }
6752 }
6753
6754 // check trade slot case (last, for allow catch any another cast problems)
6756 {
6757 if (m_CastItem)
6759
6760 if (!m_caster->IsPlayer())
6762
6763 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6764
6765 if (!my_trade)
6767
6769 if (slot != TRADE_SLOT_NONTRADED)
6771
6772 if (!IsTriggered())
6773 if (my_trade->GetSpell())
6775 }
6776
6777 // check if caster has at least 1 combo point on target for spells that require combo points
6779 {
6781 {
6783 {
6785 }
6786 }
6787 else
6788 {
6789 if (!m_caster->GetComboPoints())
6790 {
6792 }
6793 }
6794 }
6795
6796 // xinef: check relic cooldown
6800
6801 // all ok
6802 return SPELL_CAST_OK;
6803}
LineOfSightChecks
Definition: Map.h:191
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:198
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:62
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:144
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition: SpellDefines.h:151
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:145
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:180
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:198
@ STATUS_IN_PROGRESS
Definition: Battleground.h:197
@ INVTYPE_RELIC
Definition: ItemTemplate.h:284
@ HUNTER_PET
Definition: PetDefines.h:32
@ GO_STATE_READY
Definition: GameObjectData.h:691
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:497
#define WORLD_TRIGGER
Definition: Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:77
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ CLASS_CONTEXT_PET
Definition: UnitDefines.h:215
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: UnitDefines.h:285
@ UNIT_STATE_ROOT
Definition: UnitDefines.h:159
@ UNIT_STATE_CHARGING
Definition: UnitDefines.h:166
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:255
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Difficulty
Definition: DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1566
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
Powers
Definition: SharedDefines.h:268
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:644
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:807
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:862
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:930
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:852
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:879
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:863
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:821
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:887
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:796
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:891
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:940
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:873
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:931
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:904
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:835
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1427
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:504
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3683
@ PET_TAME_DEAD
Definition: SharedDefines.h:3686
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3688
@ CLASS_WARLOCK
Definition: SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1399
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
SpellCustomErrors
Definition: SharedDefines.h:1142
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1208
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:396
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:397
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:406
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:399
AuraStateType
Definition: SharedDefines.h:1288
DispelType
Definition: SharedDefines.h:1371
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1070
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:1010
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:1000
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:1013
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:950
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:971
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1035
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:1012
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:984
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:1009
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1052
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1084
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1121
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1132
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1095
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:960
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1081
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:1027
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:956
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:957
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:1020
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1036
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1032
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1115
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:1006
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:955
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1086
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:985
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:997
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:1016
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1091
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1100
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:991
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1044
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1067
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1037
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:962
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1104
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1131
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1135
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1075
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:1017
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1125
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1042
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:973
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1054
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1033
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:1005
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1056
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1039
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:1014
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:547
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3286
SkillType
Definition: SharedDefines.h:2863
@ SKILL_MINING
Definition: SharedDefines.h:2919
@ SKILL_HERBALISM
Definition: SharedDefines.h:2915
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:616
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
constexpr auto MINUTE
Definition: Common.h:47
std::int32_t int32
Definition: Define.h:103
std::uint16_t uint16
Definition: Define.h:108
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:411
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:248
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:206
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:342
Definition: Battleground.h:298
Definition: ConditionMgr.h:181
Condition * mLastFailedCondition
Definition: ConditionMgr.h:183
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:182
uint32 ErrorType
Definition: ConditionMgr.h:204
uint8 ConditionTarget
Definition: ConditionMgr.h:208
uint32 ErrorTextId
Definition: ConditionMgr.h:205
Loot loot
Definition: Creature.h:227
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:206
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2823
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:260
bool IsTameable(bool exotic) const
Definition: CreatureData.h:277
Definition: TemporarySummon.h:40
Definition: GameObject.h:121
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:137
uint32 type
Definition: GameObjectData.h:34
bool IsLocked() const
Definition: Item.h:253
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:545
bool IsPotion() const
Definition: Item.h:337
uint32 ItemLevel
Definition: ItemTemplate.h:635
uint32 LockID
Definition: ItemTemplate.h:669
uint32 InventoryType
Definition: ItemTemplate.h:632
Unit * ToUnit()
Definition: Object.h:206
Map * GetMap() const
Definition: Object.h:531
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1347
bool IsOutdoors() const
Definition: Object.cpp:3166
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1326
float GetVisibilityRange() const
Definition: Object.cpp:1645
uint32 GetAreaId() const
Definition: Object.cpp:3149
uint32 GetZoneId() const
Definition: Object.cpp:3141
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3157
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsGameObject() const
Definition: ObjectGuid.h:171
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2493
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1439
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1457
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:170
Definition: PetDefines.h:202
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228
void SetCanTeleport(bool value)
Definition: Player.h:2475
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1863
bool CanTameExoticPets() const
Definition: Player.h:2166
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13167
bool InBattleground() const
Definition: Player.h:2229
PetStable * GetPetStable()
Definition: Player.h:1202
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12149
WorldSession * GetSession() const
Definition: Player.h:1975
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16283
uint32 GetLastPotionId()
Definition: Player.h:1789
Group * GetGroup()
Definition: Player.h:2445
bool IsGameMaster() const
Definition: Player.h:1158
time_t GetSummonExpireTimer() const
Definition: Player.h:1101
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6720
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1108
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1855
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:430
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:757
Vehicle * GetVehicle() const
Definition: Unit.h:1697
Unit * GetOwner() const
Definition: Unit.cpp:10545
Pet * ToPet()
Definition: Unit.h:1741
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:1761
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1414
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:1762
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21159
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13569
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:831
bool IsInSanctuary() const
Definition: Unit.h:861
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition: Unit.h:766
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5763
float GetCombatReach() const override
Definition: Unit.h:687
UnitFlags GetUnitFlags() const
Definition: Unit.h:824
TempSummon * ToTempSummon()
Definition: Unit.h:1743
bool HasStealthAura() const
Definition: Unit.h:1050
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5652
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:652
bool IsInFlight() const
Definition: Unit.h:1020
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:1479
void SendTameFailure(uint8 result)
Definition: Unit.cpp:19929
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1617
virtual bool IsInWater() const
Definition: Unit.cpp:4304
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10492
bool isMoving() const
Definition: Unit.h:1723
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1165
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:1494
bool IsMounted() const
Definition: Unit.h:887
Unit * GetVictim() const
Definition: Unit.h:727
bool IsCritter() const
Definition: Unit.h:1018
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1157
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:1633
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1163
uint32 getTransForm() const
Definition: Unit.h:1517
virtual bool HasActivePowerType(Powers power)
Definition: Unit.h:803
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5188
bool IsTotem() const
Definition: Unit.h:756
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10596
ObjectGuid GetTarget() const
Definition: Unit.h:1776
bool IsInCombat() const
Definition: Unit.h:1032
ObjectGuid GetPetGUID() const
Definition: Unit.h:1167
Definition: Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:580
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:142
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:274
bool AllowMount
Definition: Map.h:277
bool IsDungeon() const
Definition: Map.h:448
bool IsBattlegroundOrArena() const
Definition: Map.h:456
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3319
uint32 GetId() const
Definition: Map.h:379
Difficulty GetDifficulty() const
Definition: Map.h:443
uint32 GetRecruiterId() const
Definition: WorldSession.h:526
uint32 GetAccountId() const
Definition: WorldSession.h:361
GameObject * GetGOTarget() const
Definition: Spell.cpp:265
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:776
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7737
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8349
SpellCastResult CheckItems()
Definition: Spell.cpp:7169
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7124
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6841
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8548
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7038
bool HasGlobalCooldown() const
Definition: Spell.cpp:8820
Definition: SpellInfo.h:249
int32 MiscValue
Definition: SpellInfo.h:263
uint32 ApplyAuraName
Definition: SpellInfo.h:254
uint32 PreventionType
Definition: SpellInfo.h:390
uint32 CasterAuraSpell
Definition: SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1433
uint32 Mechanic
Definition: SpellInfo.h:323
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2040
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2395
bool IsSelfCast() const
Definition: SpellInfo.cpp:1089
uint32 CasterAuraState
Definition: SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1231
uint32 CasterAuraStateNot
Definition: SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1488
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1986
int32 AreaGroupId
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2322
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2054
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1032
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:345
uint32 SpellFamilyName
Definition: SpellInfo.h:387
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1936
Definition: DBCStructure.h:519
Definition: DBCStructure.h:1021
Definition: DBCStructure.h:1325
bool IsDungeon() const
Definition: DBCStructure.h:1351
Definition: DBCStructure.h:1817
uint32 flags1
Definition: DBCStructure.h:1822
Definition: DBCStructure.h:1909
uint32 Category
Definition: DBCStructure.h:1911
Definition: DBCStructure.h:2064
uint32 m_flags
Definition: DBCStructure.h:2066

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6842{
6843 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6845 return SPELL_CAST_OK;
6846
6847 uint8 school_immune = 0;
6848 uint32 mechanic_immune = 0;
6849 uint32 dispel_immune = 0;
6850
6851 // Check if the spell grants school or mechanic immunity.
6852 // We use bitmasks so the loop is done only once and not on every aura check below.
6854 {
6855 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6856 {
6857 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6858 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6859 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6860 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6861 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6862 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6863 }
6864 // immune movement impairment and loss of control
6865 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6866 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6868 }
6869
6871
6872 // Glyph of Pain Suppression
6873 // there is no other way to handle it
6874 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6875 usableInStun = false;
6876
6877 // Check whether the cast should be prevented by any state you might have.
6878 SpellCastResult prevented_reason = SPELL_CAST_OK;
6879 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6880 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6881
6882 // Xinef: if spell is triggered check preventionType only
6883 if (!preventionOnly)
6884 {
6885 if (unitflag & UNIT_FLAG_STUNNED)
6886 {
6887 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6888 if (usableInStun)
6889 {
6890 bool foundNotStun = false;
6891 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6892 // Barkskin should skip sleep effects, sap and fears
6893 if (m_spellInfo->Id == 22812)
6894 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6895 // Hand of Freedom, can be used while sapped
6896 if (m_spellInfo->Id == 1044)
6897 mask |= 1 << MECHANIC_SAPPED;
6899 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6900 {
6901 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6902 {
6903 foundNotStun = true;
6904 break;
6905 }
6906 }
6907 if (foundNotStun)
6908 prevented_reason = SPELL_FAILED_STUNNED;
6909 }
6910 else
6911 prevented_reason = SPELL_FAILED_STUNNED;
6912 }
6914 prevented_reason = SPELL_FAILED_CONFUSED;
6916 prevented_reason = SPELL_FAILED_FLEEING;
6917 }
6918
6919 // Xinef: if there is no prevented_reason, check prevention types
6920 if (prevented_reason == SPELL_CAST_OK)
6921 {
6923 prevented_reason = SPELL_FAILED_SILENCED;
6925 prevented_reason = SPELL_FAILED_PACIFIED;
6926 }
6927
6928 // Attr must make flag drop spell totally immune from all effects
6929 if (prevented_reason != SPELL_CAST_OK)
6930 {
6931 if (school_immune || mechanic_immune || dispel_immune)
6932 {
6933 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6935 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6936 {
6937 Aura const* aura = itr->second->GetBase();
6938 SpellInfo const* auraInfo = aura->GetSpellInfo();
6939 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6940 continue;
6941 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6942 continue;
6943 if (auraInfo->GetDispelMask() & dispel_immune)
6944 continue;
6945
6946 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6947 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6948 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6949 {
6950 if (AuraEffect* part = aura->GetEffect(i))
6951 {
6952 switch (part->GetAuraType())
6953 {
6955 {
6956 uint32 mask = 1 << MECHANIC_STUN;
6957 // Barkskin should skip sleep effects, sap and fears
6958 if (m_spellInfo->Id == 22812)
6959 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6960 // Hand of Freedom, can be used while sapped
6961 if (m_spellInfo->Id == 1044)
6962 mask |= 1 << MECHANIC_SAPPED;
6963
6964 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6965 return SPELL_FAILED_STUNNED;
6966 break;
6967 }
6970 return SPELL_FAILED_CONFUSED;
6971 break;
6974 return SPELL_FAILED_FLEEING;
6975 break;
6980 return SPELL_FAILED_PACIFIED;
6982 return SPELL_FAILED_SILENCED;
6983 break;
6984 default:
6985 break;
6986 }
6987 }
6988 }
6989 }
6990 }
6991 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6992 else
6993 return prevented_reason;
6994 }
6995 return SPELL_CAST_OK;
6996}
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:247
@ UNIT_FLAG_PACIFIED
Definition: UnitDefines.h:246
@ UNIT_FLAG_CONFUSED
Definition: UnitDefines.h:251
@ UNIT_FLAG_FLEEING
Definition: UnitDefines.h:252
@ UNIT_FLAG_SILENCED
Definition: UnitDefines.h:242
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1554
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1555
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:584
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:585
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:435
@ MECHANIC_STUN
Definition: SharedDefines.h:1337
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1338
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1335
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1355
@ MECHANIC_HORROR
Definition: SharedDefines.h:1349
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1361
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1057
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:975
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1053
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:983
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1047
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:606
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:639
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1267
Definition: SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1991

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:407

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8482{
8483 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8485}
#define ASSERT
Definition: Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7915{
7916 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7917 {
7922 if (target->IsCreature() && target->IsVehicle())
7923 return false;
7924 if (target->IsMounted())
7925 return false;
7926 if (target->GetCharmerGUID())
7927 return false;
7928 if (int32 damage = CalculateSpellDamage(eff, target))
7929 if ((int32)target->GetLevel() > damage)
7930 return false;
7931 break;
7932 default:
7933 break;
7934 }
7935
7936 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7937 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7938 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7939 return true;
7940
7941 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7944 {
7945 return true;
7946 }
7947
7949 //Check targets for LOS visibility (except spells without range limitations)
7950 switch (m_spellInfo->Effects[eff].Effect)
7951 {
7953 // player far away, maybe his corpse near?
7954 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7955 {
7957 return false;
7958
7960 if (!corpse)
7961 return false;
7962
7963 if (target->GetGUID() != corpse->GetOwnerGUID())
7964 return false;
7965
7967 return false;
7968 }
7969 break;
7971 {
7973 {
7974 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7975 return true;
7976
7977 return false;
7978 }
7979
7981 if (!corpse)
7982 return false;
7983
7984 if (target->GetGUID() != corpse->GetOwnerGUID())
7985 return false;
7986
7988 return false;
7989
7991 return false;
7992 }
7993 break;
7995 if (!m_caster->IsPlayer() || !target->IsPlayer())
7996 return false;
7997 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
7998 return false;
7999 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8000 return false;
8001 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8002 return false;
8003 break;
8004 default: // normal case
8005 {
8006 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8007 GameObject* gobCaster = nullptr;
8009 {
8011 }
8012 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8013 {
8014 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8015 {
8016 gobCaster = tempSummon->GetSummonerGameObject();
8017 }
8018 }
8019
8020 if (gobCaster)
8021 {
8022 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8023 {
8024 return true;
8025 }
8026
8027 // If spell casted by gameobject then ignore M2 models
8028 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8029 }
8030
8031 if (target != m_caster)
8032 {
8033 if (m_targets.HasDst())
8034 {
8035 float x = m_targets.GetDstPos()->GetPositionX();
8036 float y = m_targets.GetDstPos()->GetPositionY();
8037 float z = m_targets.GetDstPos()->GetPositionZ();
8038
8039 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8040 {
8041 return false;
8042 }
8043 }
8045 {
8046 return false;
8047 }
8048 }
8049 break;
8050 }
8051 }
8052
8053 return true;
8054}
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ UNIT_FLAG_NOT_SELECTABLE
Definition: UnitDefines.h:254
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:251
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:894
#define sWorld
Definition: World.h:444
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:306
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:182
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObjectData.h:643
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
bool IsARecruiter() const
Definition: WorldSession.h:527
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:282

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7170{
7171 Player* player = m_caster->ToPlayer();
7172 if (!player)
7173 {
7174 // Non-player case: Check if creature is disarmed
7176 {
7178 }
7179
7180 return SPELL_CAST_OK;
7181 }
7182
7183 if (!m_CastItem)
7184 {
7185 if (m_castItemGUID)
7187 }
7188 else
7189 {
7190 uint32 itemid = m_CastItem->GetEntry();
7191 if (!player->HasItemCount(itemid))
7193
7194 ItemTemplate const* proto = m_CastItem->GetTemplate();
7195 if (!proto)
7197
7198 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7199 if (proto->Spells[i].SpellCharges)
7200 if (m_CastItem->GetSpellCharges(i) == 0)
7202
7203 // consumable cast item checks
7205 {
7206 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7207 SpellCastResult failReason = SPELL_CAST_OK;
7208 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7209 {
7210 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7211 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7212 continue;
7213
7214 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7215 {
7217 {
7219 continue;
7220 }
7221 else
7222 {
7223 failReason = SPELL_CAST_OK;
7224 break;
7225 }
7226 }
7227
7228 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7229 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7230 {
7231 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7232 {
7234 continue;
7235 }
7236
7237 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7239 {
7241 continue;
7242 }
7243 else
7244 {
7245 failReason = SPELL_CAST_OK;
7246 break;
7247 }
7248 }
7249 }
7250 if (failReason != SPELL_CAST_OK)
7251 return failReason;
7252 }
7253 }
7254
7255 // check target item
7257 {
7258 if (!m_caster->IsPlayer())
7260
7261 if (!m_targets.GetItemTarget())
7263
7266 }
7267 // if not item target then required item must be equipped
7268 else
7269 {
7270 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7271 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7274 }
7275
7276 // do not take reagents for these item casts
7278 {
7280 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7281 if (!checkReagents)
7282 if (Item* targetItem = m_targets.GetItemTarget())
7283 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7284 checkReagents = true;
7285
7286 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7287 if (checkReagents)
7288 {
7289 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7290 {
7291 if (m_spellInfo->Reagent[i] <= 0)
7292 continue;
7293
7294 uint32 itemid = m_spellInfo->Reagent[i];
7295 uint32 itemcount = m_spellInfo->ReagentCount[i];
7296
7297 // if CastItem is also spell reagent
7298 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7299 {
7300 ItemTemplate const* proto = m_CastItem->GetTemplate();
7301 if (!proto)
7303 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7304 {
7305 // CastItem will be used up and does not count as reagent
7306 int32 charges = m_CastItem->GetSpellCharges(s);
7307 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7308 {
7309 ++itemcount;
7310 break;
7311 }
7312 }
7313 }
7314 if (!player->HasItemCount(itemid, itemcount))
7315 return SPELL_FAILED_REAGENTS;
7316 }
7317 }
7318
7319 // check totem-item requirements (items presence in inventory)
7320 uint32 totems = 2;
7321 for (int i = 0; i < 2; ++i)
7322 {
7323 if (m_spellInfo->Totem[i] != 0)
7324 {
7325 if (player->HasItemCount(m_spellInfo->Totem[i]))
7326 {
7327 totems -= 1;
7328 continue;
7329 }
7330 }
7331 else
7332 totems -= 1;
7333 }
7334 if (totems != 0)
7335 return SPELL_FAILED_TOTEMS; //0x7C
7336
7337 // Check items for TotemCategory (items presence in inventory)
7339 for (int i = 0; i < 2; ++i)
7340 {
7341 if (m_spellInfo->TotemCategory[i] != 0)
7342 {
7344 {
7345 TotemCategory -= 1;
7346 continue;
7347 }
7348 }
7349 else
7350 TotemCategory -= 1;
7351 }
7352 if (TotemCategory != 0)
7353 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7354 }
7355
7356 // special checks for spell effects
7357 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7358 {
7359 switch (m_spellInfo->Effects[i].Effect)
7360 {
7363 {
7364 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7365 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7366 if (target->IsPlayer() && !IsTriggered())
7367 {
7368 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7369 // so we need to make sure there is at least one free space in the player's inventory
7371 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7372 {
7373 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7375 }
7376
7377 if (m_spellInfo->Effects[i].ItemType)
7378 {
7379 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7380 if (!itemTemplate)
7382
7383 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7384 ItemPosCountVec dest;
7385 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7386 if (msg != EQUIP_ERR_OK)
7387 {
7389 if (!itemTemplate->ItemLimitCategory)
7390 {
7391 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7393 }
7394 else
7395 {
7396 // Conjure Food/Water/Refreshment spells
7399 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7400 {
7401 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7403 }
7404 else
7405 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7406
7408 }
7409 }
7410 }
7411 }
7412 break;
7413 }
7415 {
7416 if (player->GetFreeInventorySpace() == 0)
7417 {
7418 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7420 }
7421 break;
7422 }
7424 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7426 {
7427 // cannot enchant vellum for other player
7430 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7433 ItemPosCountVec dest;
7434 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7435 if (msg != EQUIP_ERR_OK)
7436 {
7437 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7439 }
7440 }
7441 [[fallthrough]];
7443 {
7444 Item* targetItem = m_targets.GetItemTarget();
7445 if (!targetItem)
7447
7448 // xinef: required level has to be checked also! Exploit fix
7449 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7450 return SPELL_FAILED_LOWLEVEL;
7451
7452 bool isItemUsable = false;
7453 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7454 {
7455 ItemTemplate const* proto = targetItem->GetTemplate();
7456 if (proto->Spells[e].SpellId && (
7459 {
7460 isItemUsable = true;
7461 break;
7462 }
7463 }
7464
7465 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7466 // do not allow adding usable enchantments to items that have use effect already
7467 if (enchantEntry)
7468 {
7469 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7470 {
7471 switch (enchantEntry->type[s])
7472 {
7474 if (isItemUsable)
7476 break;
7478 {
7479 uint32 numSockets = 0;
7480 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7481 if (targetItem->GetTemplate()->Socket[socket].Color)
7482 ++numSockets;
7483
7484 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7486 break;
7487 }
7488 }
7489 }
7490 }
7491
7492 // Not allow enchant in trade slot for some enchant type
7493 if (targetItem->GetOwner() != m_caster)
7494 {
7495 if (!enchantEntry)
7496 return SPELL_FAILED_ERROR;
7497 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7499 }
7500 break;
7501 }
7503 {
7504 Item* item = m_targets.GetItemTarget();
7505 if (!item)
7507 // Not allow enchant in trade slot for some enchant type
7508 if (item->GetOwner() != m_caster)
7509 {
7510 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7511 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7512 if (!pEnchant)
7513 return SPELL_FAILED_ERROR;
7514 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7516 }
7517
7518 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7519 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7520 {
7522 return SPELL_FAILED_LOWLEVEL;
7523 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7525 }
7526
7527 break;
7528 }
7530 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7531 break;
7533 {
7534 if (!m_targets.GetItemTarget())
7536
7537 // prevent disenchanting in trade slot
7540
7541 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7542 if (!itemProto)
7544
7545 uint32 item_quality = itemProto->Quality;
7546 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7547 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7548 if (item_disenchantskilllevel == uint32(-1))
7550 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7552 if (item_quality > 4 || item_quality < 2)
7554 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7556 if (!itemProto->DisenchantID)
7558 break;
7559 }
7561 {
7562 if (!m_targets.GetItemTarget())
7564 //ensure item is a prospectable ore
7567 //prevent prospecting in trade slot
7570 //Check for enough skill in jewelcrafting
7571 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7572 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7574 //make sure the player has the required ores in inventory
7575 if (m_targets.GetItemTarget()->GetCount() < 5)
7577
7580
7581 break;
7582 }
7584 {
7585 if (!m_targets.GetItemTarget())
7587 //ensure item is a millable herb
7590 //prevent milling in trade slot
7593 //Check for enough skill in inscription
7594 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7595 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7597 //make sure the player has the required herbs in inventory
7598 if (m_targets.GetItemTarget()->GetCount() < 5)
7600
7603
7604 break;
7605 }
7608 {
7609 if (!m_caster->IsPlayer())
7611
7613 break;
7614
7616 if (!pItem || pItem->IsBroken())
7618
7619 switch (pItem->GetTemplate()->SubClass)
7620 {
7622 {
7623 uint32 ammo = pItem->GetEntry();
7624 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7625 return SPELL_FAILED_NO_AMMO;
7626 };
7627 break;
7631 {
7633 if (!ammo)
7634 {
7635 // Requires No Ammo
7636 if (m_caster->HasAura(46699))
7637 break; // skip other checks
7638
7639 return SPELL_FAILED_NO_AMMO;
7640 }
7641
7642 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7643 if (!ammoProto)
7644 return SPELL_FAILED_NO_AMMO;
7645
7646 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7647 return SPELL_FAILED_NO_AMMO;
7648
7649 // check ammo ws. weapon compatibility
7650 switch (pItem->GetTemplate()->SubClass)
7651 {
7654 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7655 return SPELL_FAILED_NO_AMMO;
7656 break;
7658 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7659 return SPELL_FAILED_NO_AMMO;
7660 break;
7661 default:
7662 return SPELL_FAILED_NO_AMMO;
7663 }
7664
7665 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7666 {
7668 return SPELL_FAILED_NO_AMMO;
7669 }
7670 };
7671 break;
7673 break;
7674 default:
7675 break;
7676 }
7677 break;
7678 }
7680 {
7681 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7682 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7683
7684 if (!pProto)
7686
7687 if (Item* pitem = player->GetItemByEntry(item_id))
7688 {
7689 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7690 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7692 }
7693 break;
7694 }
7695 default:
7696 break;
7697 }
7698 }
7699
7700 // check weapon presence in slots for main/offhand weapons
7701 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7702 {
7703 // main hand weapon required
7705 {
7707
7708 // skip spell if no weapon in slot or broken
7709 if (!item || item->IsBroken())
7711
7712 // skip spell if weapon not fit to triggered spell
7715 }
7716
7717 // offhand hand weapon required
7719 {
7721
7722 // skip spell if no weapon in slot or broken
7723 if (!item || item->IsBroken())
7725
7726 // skip spell if weapon not fit to triggered spell
7729 }
7730
7732 }
7733
7734 return SPELL_CAST_OK;
7735}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_OK
Definition: Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
#define MAX_ITEM_SPELLS
Definition: Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:201
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:291
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:771
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:374
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1639
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1838
@ EFFECT_1
Definition: SharedDefines.h:32
@ MAX_POWERS
Definition: SharedDefines.h:276
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:877
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:905
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:936
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:844
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:837
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:503
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
TotemCategory
Definition: SharedDefines.h:3083
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:980
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:978
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1128
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1071
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:953
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:1019
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:994
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:1025
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:992
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:1024
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:993
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:977
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:951
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1119
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1080
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:981
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1049
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1133
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1078
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:1004
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:966
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:979
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1079
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:3002
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2985
std::int8_t int8
Definition: Define.h:105
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:317
bool IsBroken() const
Definition: Item.h:257
bool IsWeaponVellum() const
Definition: Item.h:338
bool IsArmorVellum() const
Definition: Item.h:339
Player * GetOwner() const
Definition: Item.cpp:550
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
uint32 GetCount() const
Definition: Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:885
int32 SpellCharges
Definition: ItemTemplate.h:593
uint32 SpellTrigger
Definition: ItemTemplate.h:592
int32 SpellId
Definition: ItemTemplate.h:591
uint32 Color
Definition: ItemTemplate.h:602
Definition: ItemTemplate.h:619
uint32 DisenchantID
Definition: ItemTemplate.h:690
uint32 Quality
Definition: ItemTemplate.h:626
uint32 RequiredSkillRank
Definition: ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:684
uint32 RequiredLevel
Definition: ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
uint32 Class
Definition: ItemTemplate.h:621
uint32 ItemLimitCategory
Definition: ItemTemplate.h:687
uint32 SubClass
Definition: ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:681
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12463
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:489
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3384
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:678
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:874
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12508
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4036
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1272
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:952
bool IsFullHealth() const
Definition: Unit.h:785
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:805
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21214
uint32 GetPower(Powers power) const
Definition: Unit.h:804
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:140
ObjectGuid m_castItemGUID
Definition: Spell.h:523
uint32 BaseLevel
Definition: SpellInfo.h:359
uint32 MaxLevel
Definition: SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:373
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:378
int32 EquippedItemClass
Definition: SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:374
Definition: DBCStructure.h:1841
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1844
uint32 slot
Definition: DBCStructure.h:1851

References BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6806{
6807 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6809
6810 // dead owner (pets still alive when owners ressed?)
6811 if (Unit* owner = m_caster->GetCharmerOrOwner())
6812 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6814
6815 if (!target && m_targets.GetUnitTarget())
6816 target = m_targets.GetUnitTarget();
6817
6819 {
6820 if (!target)
6822 m_targets.SetUnitTarget(target);
6823 }
6824
6825 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6827
6828 // cooldown
6829 if (Creature const* creatureCaster = m_caster->ToCreature())
6830 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6832
6833 // Check if spell is affected by GCD
6837
6838 return CheckCast(true);
6839}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: CharmInfo.cpp:404
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:240
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2400
uint32 StartRecoveryCategory
Definition: SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7125{
7126 // item cast not used power
7127 if (m_CastItem)
7128 return SPELL_CAST_OK;
7129
7130 //While .cheat power is enabled dont check if we need power to cast the spell
7131 if (m_caster->IsPlayer())
7132 {
7134 {
7135 return SPELL_CAST_OK;
7136 }
7137 }
7138
7139 // health as power used - need check health amount
7141 {
7144 return SPELL_CAST_OK;
7145 }
7146 // Check valid power type
7148 {
7149 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7150 return SPELL_FAILED_UNKNOWN;
7151 }
7152
7153 //check rune cost only if a spell has PowerType == POWER_RUNE
7155 {
7157 if (failReason != SPELL_CAST_OK)
7158 return failReason;
7159 }
7160
7161 // Check power amount
7164 return SPELL_FAILED_NO_POWER;
7165 else
7166 return SPELL_CAST_OK;
7167}
PowerType
Definition: VehicleDefines.h:29
@ CHEAT_POWER
Definition: Player.h:1002
@ POWER_HEALTH
Definition: SharedDefines.h:278
@ POWER_RUNE
Definition: SharedDefines.h:274
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1034
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1136
uint32 GetHealth() const
Definition: Unit.h:782
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5399
uint32 RuneCostID
Definition: SpellInfo.h:368
uint32 PowerType
Definition: SpellInfo.h:362

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7039{
7040 // Don't check for instant cast spells
7041 if (!strict && m_casttime == 0)
7042 return SPELL_CAST_OK;
7043
7044 uint32 range_type = 0;
7045
7047 {
7048 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7049 // these are triggered by other spells - possibly we should omit range check in that case?
7050 if (m_spellInfo->RangeEntry->ID == 1)
7051 return SPELL_CAST_OK;
7052
7053 range_type = m_spellInfo->RangeEntry->Flags;
7054 }
7055
7056 Unit* target = m_targets.GetUnitTarget();
7057 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7058 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7059
7060 // xinef: hack for npc shooters
7061 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7062 range_type = SPELL_RANGE_RANGED;
7063
7064 if (Player* modOwner = m_caster->GetSpellModOwner())
7065 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7066
7067 // xinef: dont check max_range to strictly after cast
7068 if (range_type != SPELL_RANGE_MELEE && !strict)
7069 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7070
7071 if (target)
7072 {
7073 if (target != m_caster)
7074 {
7075 // Xinef: Spells with 5yd range can hit target 9yd away?
7076 if (range_type == SPELL_RANGE_MELEE)
7077 {
7078 float real_max_range = max_range;
7079 if (!m_caster->IsCreature() && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7080 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7081 else
7082 real_max_range -= 2 * MIN_MELEE_REACH;
7083
7084 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7086 }
7087 else if (!m_caster->IsWithinCombatRange(target, max_range))
7088 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7089
7091 {
7092 if (m_caster->IsWithinMeleeRange(target))
7094 }
7095
7096 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7098 }
7099
7100 // Xinef: check min range for self casts
7101 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7103 }
7104
7105 if (GameObject* goTarget = m_targets.GetGOTarget())
7106 {
7107 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7108 {
7110 }
7111 }
7112
7113 if (m_targets.HasDst() && !m_targets.HasTraj())
7114 {
7115 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7117 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7119 }
7120
7121 return SPELL_CAST_OK;
7122}
@ SPELL_RANGE_MELEE
Definition: Spell.h:89
@ SPELL_RANGE_RANGED
Definition: Spell.h:90
@ SPELLMOD_RANGE
Definition: SpellDefines.h:82
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:126
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1077
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1295
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:649
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15105
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:665
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15085
bool IsWalking() const
Definition: Unit.h:1722
Unit * GetCaster() const
Definition: Spell.h:573
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 FacingCasterFlags
Definition: SpellInfo.h:338
uint32 Flags
Definition: DBCStructure.h:1797
uint32 ID
Definition: DBCStructure.h:1794

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsWalking(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5400{
5401 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5402 return SPELL_CAST_OK;
5403
5404 if (!m_caster->IsPlayer())
5405 return SPELL_CAST_OK;
5406
5407 Player* player = m_caster->ToPlayer();
5408 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5409 if (player->GetCommandStatus(CHEAT_POWER))
5410 {
5411 return SPELL_CAST_OK;
5412 }
5413
5415 return SPELL_CAST_OK;
5416
5417 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5418
5419 if (!src)
5420 return SPELL_CAST_OK;
5421
5422 if (src->NoRuneCost())
5423 return SPELL_CAST_OK;
5424
5425 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5426
5427 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5428 {
5429 runeCost[i] = src->RuneCost[i];
5430 if (Player* modOwner = m_caster->GetSpellModOwner())
5431 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5432 }
5433
5434 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5435
5436 for (uint32 i = 0; i < MAX_RUNES; ++i)
5437 {
5438 RuneType rune = player->GetCurrentRune(i);
5439 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5440 runeCost[rune]--;
5441 }
5442
5443 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5444 if (runeCost[i] > 0)
5445 runeCost[RUNE_DEATH] += runeCost[i];
5446
5447 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5448 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5449
5450 return SPELL_CAST_OK;
5451}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
@ SPELLMOD_COST
Definition: SpellDefines.h:91
RuneType
Definition: Player.h:408
@ RUNE_DEATH
Definition: Player.h:412
@ NUM_RUNE_TYPES
Definition: Player.h:413
#define MAX_RUNES
Definition: Player.h:398
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2485
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1280
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2484
Definition: DBCStructure.h:1805
uint32 RuneCost[3]
Definition: DBCStructure.h:1807
bool NoRuneCost() const
Definition: DBCStructure.h:1810

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8703{
8704 // Skip if there are not any script
8705 if (!m_loadedScripts.size())
8706 return true;
8707
8708 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8709 {
8710 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8711 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8712 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8713 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8714 return false;
8715
8716 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8717 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8718 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8719 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8720 return false;
8721 }
8722 return true;
8723}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7738{
7739 // check spell focus object
7741 {
7743 Cell cell(p);
7744
7745 GameObject* ok = nullptr;
7748
7750 Map& map = *m_caster->GetMap();
7751 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7752
7753 if (!ok)
7755
7756 focusObject = ok; // game object found in range
7757 }
7758 return SPELL_CAST_OK;
7759}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1051
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: TypeContainer.h:101
Definition: TypeContainerVisitor.h:84
Definition: Cell.h:46
Definition: GridNotifiers.h:319
Definition: GridNotifiers.h:657
Definition: Map.h:313
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:873
uint32 RequiresSpellFocus
Definition: SpellInfo.h:337

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition: Spell.h:164
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:368

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2373{
2374 m_UniqueTargetInfo.clear();
2375 m_UniqueGOTargetInfo.clear();
2376 m_UniqueItemInfo.clear();
2377 m_delayMoment = 0;
2379}
uint64 m_delayTrajectory
Definition: Spell.h:640

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7762{
7763 if (!m_caster)// || !m_caster->IsPlayer())
7764 return;
7765
7766 //if (m_spellState == SPELL_STATE_DELAYED)
7767 // return; // spell is active and can't be time-backed
7768
7769 if (isDelayableNoMore()) // Spells may only be delayed twice
7770 return;
7771
7773 return;
7774
7775 // spells not loosing casting time (slam, dynamites, bombs..)
7776 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7777 // return;
7778
7779 //check pushback reduce
7780 int32 delaytime = 500; // spellcasting delay is normally 500ms
7781 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7784 if (delayReduce >= 100)
7785 return;
7786
7787 AddPct(delaytime, -delayReduce);
7788
7789 if (m_timer + delaytime > m_casttime)
7790 {
7791 delaytime = m_casttime - m_timer;
7793 }
7794 else
7795 m_timer += delaytime;
7796
7797 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7798
7799 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7800 data << m_caster->GetPackGUID();
7801 data << uint32(delaytime);
7802
7803 m_caster->SendMessageToSet(&data, true);
7804}
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:86
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:111
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2080
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9686
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5864
Definition: WorldPacket.h:27
bool isDelayableNoMore()
Definition: Spell.h:628

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7807{
7809 return;
7810
7811 if (isDelayableNoMore()) // Spells may only be delayed twice
7812 return;
7813
7815 return;
7816
7817 //check pushback reduce
7818 // should be affected by modifiers, not take the dbc duration.
7820
7821 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7822 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7825 if (delayReduce >= 100)
7826 return;
7827
7828 AddPct(delaytime, -delayReduce);
7829
7830 if (m_timer <= delaytime)
7831 {
7832 delaytime = m_timer;
7833 m_timer = 0;
7834 }
7835 else
7836 m_timer -= delaytime;
7837
7838 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7839
7840 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7841 if ((*ihit).missCondition == SPELL_MISS_NONE)
7842 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7843 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7844
7845 // partially interrupt persistent area auras
7847 dynObj->Delay(delaytime);
7848
7850}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6082
uint32 getState() const
Definition: Spell.h:482
int32 GetDuration() const
Definition: SpellInfo.cpp:2337

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8290{
8291 Unit* unit = nullptr;
8292 // In case spell hit target, do all effect on that target
8293 if (targetInfo.missCondition == SPELL_MISS_NONE)
8294 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8295 // In case spell reflect from target, do all effect on caster (if hit)
8296 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8297 unit = m_caster;
8298 if (!unit)
8299 return;
8300
8301 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8302 {
8303 if (targetInfo.effectMask & (1 << i))
8304 {
8305 m_damage = 0;
8306 m_healing = 0;
8307
8308 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8309
8310 if (m_damage > 0)
8311 {
8312 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8313 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8314 {
8316 if (m_caster->IsPlayer())
8317 {
8318 uint32 targetAmount = m_UniqueTargetInfo.size();
8319 if (targetAmount > 10)
8320 m_damage = m_damage * 10 / targetAmount;
8321 }
8322 }
8323 }
8324
8325 if (m_applyMultiplierMask & (1 << i))
8326 {
8328 m_damageMultipliers[i] *= multiplier[i];
8329 }
8330 targetInfo.damage += m_damage;
8331 }
8332 }
8333
8334 // xinef: totem's inherit owner crit chance and dancing rune weapon
8335 Unit* caster = m_caster;
8336 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8337 {
8338 if (Unit* owner = m_caster->GetOwner())
8339 caster = owner;
8340 }
8341 else if (m_originalCaster)
8342 caster = m_originalCaster;
8343
8344 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8345 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8346 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8347}
bool roll_chance_f(float chance)
Definition: Random.h:53
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:12009
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:11934
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit *caster) const
Definition: Unit.cpp:20308
uint32 SchoolMask
Definition: SpellInfo.h:392

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), ObjectAccessor::GetUnit(), HandleEffects(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3334{
3335 if (target->processed) // Check target
3336 return;
3337 target->processed = true; // Target checked in apply effects procedure
3338
3339 uint32 effectMask = target->effectMask;
3340 if (!effectMask)
3341 return;
3342
3343 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3344 if (!go)
3345 return;
3346
3349
3350 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3351 if (effectMask & (1 << effectNumber))
3352 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3353
3354 // xinef: inform ai about spellhit
3356
3358
3360}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:67
GameObjectAI * AI() const
Definition: GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8621
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8634
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8647

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3363{
3364 uint32 effectMask = target->effectMask;
3365 if (!target->item || !effectMask)
3366 return;
3367
3370
3371 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3372 if (effectMask & (1 << effectNumber))
3373 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3374
3376
3378}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2611{
2612 if (!target || target->processed)
2613 return;
2614
2615 target->processed = true; // Target checked in apply effects procedure
2616
2617 // Get mask of effects for target
2618 uint8 mask = target->effectMask;
2619
2620 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2621 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2622 return;
2623
2624 if (!effectUnit || m_spellInfo->Id == 45927)
2625 {
2626 uint8 farMask = 0;
2627 // create far target mask
2628 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2629 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2630 if ((1 << i) & mask)
2631 farMask |= (1 << i);
2632
2633 if (!farMask)
2634 return;
2635 // find unit in world
2636 // Xinef: FindUnit Access without Map check!!! Intended
2637 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2638 if (!effectUnit)
2639 return;
2640
2641 // do far effects on the unit
2642 // can't use default call because of threading, do stuff as fast as possible
2643 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2644 if (farMask & (1 << i))
2645 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2646 return;
2647 }
2648
2649 if (effectUnit->IsAlive() != target->alive)
2650 return;
2651
2652 // Xinef: absorb delayed projectiles for 500ms
2654 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2655 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2656 )
2657 return; // No missinfo in that case
2658
2659 // Get original caster (if exist) and calculate damage/healing from him data
2661
2662 // Skip if m_originalCaster not avaiable
2663 if (!caster)
2664 return;
2665
2666 SpellMissInfo missInfo = target->missCondition;
2667
2668 // Need init unitTarget by default unit (can changed in code on reflect)
2669 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2670 unitTarget = effectUnit;
2671
2672 // Reset damage/healing counter
2673 m_damage = target->damage;
2674 m_healing = -target->damage;
2675
2676 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2677
2680
2681 //Spells with this flag cannot trigger if effect is casted on self
2683 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2684 Unit* spellHitTarget = nullptr;
2685
2686 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2687 spellHitTarget = unitTarget;
2688 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2689 {
2690 missInfo = target->reflectResult;
2691 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2692 {
2693 spellHitTarget = m_caster;
2695 if (m_caster->IsCreature())
2697 }
2698 }
2699
2700 if (spellHitTarget)
2701 {
2702 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2703 if (missInfo2 != SPELL_MISS_NONE)
2704 {
2705 if (missInfo2 != SPELL_MISS_MISS)
2706 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2707 m_damage = 0;
2708 spellHitTarget = nullptr;
2709
2710 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2711 if (missInfo2 == SPELL_MISS_EVADE)
2712 missInfo = SPELL_MISS_EVADE;
2713 }
2714 }
2715
2716 // Do not take combo points on dodge and miss
2717 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2718 {
2719 m_needComboPoints = false;
2720 // Restore spell mods for a miss/dodge/parry Cold Blood
2722 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2723 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2724 }
2725
2726 // Fill base trigger info
2727 uint32 procAttacker = m_procAttacker;
2728 uint32 procVictim = m_procVictim;
2729 uint32 procEx = m_procEx;
2730
2731 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2732 if (canEffectTrigger && !procAttacker && !procVictim)
2733 {
2734 bool positive = true;
2735 if (m_damage > 0)
2736 positive = false;
2737 else if (!m_healing)
2738 {
2739 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2740 // If at least one effect negative spell is negative hit
2741 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2742 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2743 {
2744 positive = false;
2745 break;
2746 }
2747 }
2748 switch (m_spellInfo->DmgClass)
2749 {
2751 if (positive)
2752 {
2755 }
2756 else
2757 {
2760 }
2761 break;
2763 if (positive)
2764 {
2767 }
2768 else
2769 {
2772 }
2773 break;
2774 }
2775 }
2777
2778 // All calculated do it!
2779 // Do healing and triggers
2780 if (m_healing > 0)
2781 {
2782 bool crit = target->crit;
2783 uint32 addhealth = m_healing;
2784
2785 if (crit)
2786 {
2787 procEx |= PROC_EX_CRITICAL_HIT;
2788 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2789 }
2790 else
2791 procEx |= PROC_EX_NORMAL_HIT;
2792
2793 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2794
2795 // Xinef: override with forced crit, only visual result
2796 if (GetSpellValue()->ForcedCritResult)
2797 {
2798 crit = true;
2799 procEx |= PROC_EX_CRITICAL_HIT;
2800 }
2801
2802 int32 gain = caster->HealBySpell(healInfo, crit);
2803 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2804 m_healing = gain;
2805
2806 // Xinef: if heal acutally healed something, add no overheal flag
2807 if (m_healing)
2808 procEx |= PROC_EX_NO_OVERHEAL;
2809
2810 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2811 if (canEffectTrigger)
2812 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2813 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2814 }
2815 // Do damage and triggers
2816 else if (m_damage > 0)
2817 {
2819
2820 // Fill base damage struct (unitTarget - is real spell target)
2822
2823 // Add bonuses and fill damageInfo struct
2824 // Dancing Rune Weapon...
2825 if (m_caster->GetEntry() == 27893)
2826 {
2827 if (Unit* owner = m_caster->GetOwner())
2828 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2829 }
2830 else
2831 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2832
2833 // xinef: override miss info after absorb / block calculations
2834 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2835 {
2836 //if (damageInfo.absorb > 0)
2837 // missInfo = SPELL_MISS_ABSORB;
2838 if (damageInfo.blocked)
2839 missInfo = SPELL_MISS_BLOCK;
2840 }
2841
2842 // Xinef: override with forced crit, only visual result
2843 if (GetSpellValue()->ForcedCritResult)
2844 {
2845 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2846 }
2847
2848 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2849
2850 // xinef: health leech handling
2852 {
2853 uint8 effIndex = EFFECT_0;
2854 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2855 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2856 break;
2857
2858 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2859
2860 // get max possible damage, don't count overkill for heal
2861 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2862
2863 if (m_caster->IsAlive())
2864 {
2865 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2866 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2867
2868 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2869 m_caster->HealBySpell(healInfo);
2870 }
2871 }
2872
2873 // Send log damage message to client
2874 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2875 // Xinef: send info to target about reflect
2876 if (reflectedSpell)
2877 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2878
2879 procEx |= createProcExtendMask(&damageInfo, missInfo);
2880 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2881
2882 caster->DealSpellDamage(&damageInfo, true, this);
2883
2884 // do procs after damage, eg healing effects
2885 // no need to check if target is alive, done in procdamageandspell
2886
2887 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2888 if (canEffectTrigger)
2889 {
2890 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2891 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2892 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2893
2896 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2897 }
2898
2899 m_damage = damageInfo.damage;
2900 }
2901 // Passive spell hits/misses or active spells only misses (only triggers)
2902 else
2903 {
2904 // Fill base damage struct (unitTarget - is real spell target)
2906 procEx |= createProcExtendMask(&damageInfo, missInfo);
2907 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2908 if (canEffectTrigger)
2909 {
2910 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2911 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2912 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2913
2914 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2915 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2919 }
2920
2921 // Failed Pickpocket, reveal rogue
2923 {
2927 }
2928 }
2929
2930 if (m_caster)
2931 {
2933 {
2935
2936 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2937 if (effectUnit->IsInCombatWith(m_caster))
2938 {
2939 if (Creature* creature = effectUnit->ToCreature())
2940 {
2941 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2942 {
2943 creature->SetLootRecipient(m_caster);
2944 }
2945 }
2946 }
2947
2948 // Unsure if there are more spells that are not supposed to stop enemy from
2949 // regenerating HP from food, so for now it stays as an ID.
2950 const uint32 SPELL_PREMEDITATION = 14183;
2951 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2952 {
2953 if (!effectUnit->IsStandState())
2954 {
2956 }
2957 }
2958 }
2959 }
2960
2961 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2963 {
2964 m_caster->SetInCombatWith(effectUnit);
2965 }
2966
2967 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2969 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2970
2971 if (spellHitTarget)
2972 {
2973 //AI functions
2974 if (spellHitTarget->IsCreature())
2975 {
2976 if (spellHitTarget->ToCreature()->IsAIEnabled)
2977 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2978 }
2979
2981 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2982
2983 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2984 DoTriggersOnSpellHit(spellHitTarget, mask);
2985
2986 // if target is fallged for pvp also flag caster if a player
2987 // xinef: do not flag spells with aura bind sight (no special attribute)
2988 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2990 {
2991 m_caster->ToPlayer()->UpdatePvP(true);
2992 }
2993
2995 }
2996}
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:267
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:15933
@ NODAMAGE
Definition: Unit.h:252
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:249
@ HEAL
Definition: Unit.h:251
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:32
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:787
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR3_SUPRESS_CASTER_PROCS
Definition: SharedDefines.h:509
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:402
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1536
SpellMissInfo
Definition: SharedDefines.h:1518
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1522
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1527
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1521
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1520
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1524
@ SPELL_ATTR4_SUPRESS_WEAPON_PROCS
Definition: SharedDefines.h:553
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:27
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:146
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:143
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3793
CreatureAI * AI() const
Definition: Creature.h:143
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9892
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7156
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1480
Definition: Unit.h:330
Definition: Unit.h:373
Definition: Unit.h:489
uint32 m_lastSanctuaryTime
Definition: Unit.h:1480
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1425
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6399
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6232
bool CanProc()
Definition: Unit.h:1663
bool IsPvP() const
Definition: Unit.h:862
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12392
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13521
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11184
bool IsStandState() const
Definition: Unit.cpp:16659
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:20952
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:1492
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14063
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12261
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6264
bool IsAIEnabled
Definition: Unit.h:1693
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:917
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12510
void SetStandState(uint8 state)
Definition: Unit.cpp:16665
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5135
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:787
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1282
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:217
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8725
SpellValue const * GetSpellValue()
Definition: Spell.h:583
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:2998
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3256
uint32 AttributesEx3
Definition: SpellInfo.h:327
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1024
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1241

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_SUPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1636{
1637 if (!unitTarget)
1638 return;
1639
1640 Player* player = unitTarget->ToPlayer();
1641 if (!player)
1642 {
1643 return;
1644 }
1645
1646 uint32 newitemid = itemId;
1647
1648 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1649 if (!pProto)
1650 {
1651 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1652 return;
1653 }
1654
1655 uint32 addNumber = damage;
1656
1657 // bg reward have some special in code work
1658 bool SelfCast = true;
1659 switch (m_spellInfo->Id)
1660 {
1665 case SPELL_WS_MARK_TIE:
1668 SelfCast = true;
1669 break;
1671 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1672 addNumber = 3;
1673 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1674 addNumber = 2;
1675 else
1676 addNumber = 1;
1677 SelfCast = true;
1678 break;
1679 }
1680
1681 if (addNumber < 1)
1682 addNumber = 1;
1683 if (addNumber > pProto->GetMaxStackSize())
1684 addNumber = pProto->GetMaxStackSize();
1685
1686 /* == gem perfection handling == */
1687
1688 // the chance of getting a perfect result
1689 float perfectCreateChance = 0.0f;
1690
1691 // the resulting perfect item if successful
1692 uint32 perfectItemType = itemId;
1693
1694 // get perfection capability and chance
1695 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1696 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1697 newitemid = perfectItemType; // the perfect item replaces the regular one
1698
1699 /* == gem perfection handling over == */
1700
1701 /* == profession specialization handling == */
1702
1703 // init items_count to 1, since 1 item will be created regardless of specialization
1704 int32 itemsCount = 1;
1705 float additionalCreateChance = 0.0f;
1706 int32 additionalMaxNum = 0;
1707 // get the chance and maximum number for creating extra items
1708 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1709 {
1710 // roll with this chance till we roll not to create or we create the max num
1711 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1712 ++itemsCount;
1713 }
1714
1715 // really will be created more items
1716 addNumber *= itemsCount;
1717
1718 /* == profession specialization handling over == */
1719
1720 // can the player store the new item?
1721 ItemPosCountVec dest;
1722 uint32 no_space = 0;
1723 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1724 if (msg != EQUIP_ERR_OK)
1725 {
1726 // convert to possible store amount
1728 addNumber -= no_space;
1729 else
1730 {
1731 // if not created by another reason from full inventory or unique items amount limitation
1732 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1733 return;
1734 }
1735 }
1736
1737 if (addNumber)
1738 {
1739 // create the new item and store it
1740 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1741
1742 // was it successful? return error if not
1743 if (!pItem)
1744 {
1745 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1746 return;
1747 }
1748
1749 // set the "Crafted by ..." property of the item
1750 if (pItem->GetTemplate()->HasSignature())
1751 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1752
1753 // send info to the client
1754 player->SendNewItem(pItem, addNumber, true, SelfCast);
1755
1756 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1757
1758 // we succeeded in creating at least one item, so a levelup is possible
1759 if (SelfCast)
1761 }
1762}
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition: SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition: SkillExtraItems.cpp:202
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:101
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:102
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:100
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:103
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:104
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:106
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
bool HasSignature() const
Definition: ItemTemplate.h:698
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:781
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4765
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2539

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, ITEM_FIELD_CREATOR, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2999{
3000 if (!unit || !effectMask)
3001 return SPELL_MISS_EVADE;
3002
3003 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3004 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3005 {
3006 return SPELL_MISS_IMMUNE;
3007 }
3008
3009 // disable effects to which unit is immune
3010 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3011 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3012 {
3013 if (effectMask & (1 << effectNumber))
3014 {
3015 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3016 effectMask &= ~(1 << effectNumber);
3017 // Xinef: Buggs out polymorph
3018 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3019 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3020 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3021 {
3022 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3023 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3024
3025 if (debuff_resist_chance > 0)
3026 if (irand(0,10000) <= (debuff_resist_chance * 100))
3027 {
3028 effectMask &= ~(1 << effectNumber);
3029 returnVal = SPELL_MISS_RESIST;
3030 }
3031 }*/
3032 }
3033 }
3034 if (!effectMask)
3035 return returnVal;
3036
3037 if (unit->IsPlayer())
3038 {
3042 }
3043
3044 if (m_caster->IsPlayer())
3045 {
3048 }
3049
3050 if (m_caster != unit)
3051 {
3052 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3053 // Xinef: Also check evade state
3054 if (m_spellInfo->Speed > 0.0f)
3055 {
3056 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3057 return SPELL_MISS_EVADE;
3058
3060 return SPELL_MISS_EVADE;
3061 }
3062
3063 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3064 {
3066 }
3067 else if (m_caster->IsFriendlyTo(unit))
3068 {
3069 // for delayed spells ignore negative spells (after duel end) for friendly targets
3071 if(!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3072 return SPELL_MISS_EVADE;
3073
3074 // assisting case, healing and resurrection
3076 {
3079 m_caster->ToPlayer()->UpdatePvP(true);
3080 }
3081
3082 // xinef: triggered spells should not prolong combat
3084 {
3085 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3086 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3087 }
3088 }
3089 }
3090
3091 uint8 aura_effmask = 0;
3092 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3093 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3094 aura_effmask |= 1 << i;
3095
3096 Unit* originalCaster = GetOriginalCaster();
3097 if (!originalCaster)
3098 originalCaster = m_caster;
3099
3100 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3101 // Xinef: Do not increase diminishing level for self cast
3103 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3105 {
3108
3109 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3110
3111 // Increase Diminishing on unit, current informations for actually casts will use values above
3112 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3114 {
3115 // Do not apply diminish return if caster is NPC
3117 {
3119 }
3120 }
3121 }
3122
3124 {
3126 }
3127
3128 if (aura_effmask)
3129 {
3130 // Select rank for aura with level requirements only in specific cases
3131 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3132 SpellInfo const* aurSpellInfo = m_spellInfo;
3133 int32 basePoints[3];
3134 if (scaleAura)
3135 {
3137 ASSERT(aurSpellInfo);
3138 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3139 {
3140 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3141 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3142 {
3143 aurSpellInfo = m_spellInfo;
3144 break;
3145 }
3146 }
3147 }
3148
3149 if (m_originalCaster)
3150 {
3151 bool refresh = false;
3153 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3154 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3155
3156 // xinef: if aura was not refreshed, add proc ex
3157 if (!refresh)
3159
3160 if (m_spellAura)
3161 {
3162 // Set aura stack amount to desired value
3164 {
3165 if (!refresh)
3167 else
3169 }
3170
3171 // Now Reduce spell duration using data received at spell hit
3172 int32 duration = m_spellAura->GetMaxDuration();
3173 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3174
3175 // Xinef: if unit == caster - test versus original unit if available
3176 float diminishMod = 1.0f;
3177 if (unit == m_caster && m_targets.GetUnitTarget())
3179 else
3180 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3181
3182 // unit is immune to aura if it was diminished to 0 duration
3183 if (diminishMod == 0.0f)
3184 {
3187 return SPELL_MISS_IMMUNE;
3188 bool found = false;
3189 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3190 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3191 found = true;
3192 if (!found)
3193 return SPELL_MISS_IMMUNE;
3194 }
3195 else
3196 {
3197 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3198
3199 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3201 positive = aurApp->IsPositive();
3202
3203 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3204
3205 // xinef: haste affects duration of those spells twice
3208
3209 if (m_spellValue->AuraDuration != 0)
3210 {
3211 if (m_spellAura->GetMaxDuration() != -1)
3212 {
3214 }
3215
3217 }
3218 else if (duration != m_spellAura->GetMaxDuration())
3219 {
3220 m_spellAura->SetMaxDuration(duration);
3221 m_spellAura->SetDuration(duration);
3222 }
3223
3224 // xinef: apply relic cooldown, imo best place to add this
3227
3230 }
3231 }
3232 }
3233 }
3234
3235 int8 sanct_effect = -1;
3236
3237 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3238 {
3239 // handle sanctuary effects after aura apply!
3240 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3241 {
3242 sanct_effect = effectNumber;
3243 continue;
3244 }
3245
3246 if (effectMask & (1 << effectNumber))
3247 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3248 }
3249
3250 if( sanct_effect >= 0 && (effectMask & (1 << sanct_effect)) )
3251 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3252
3253 return SPELL_MISS_NONE;
3254}
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:44
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:150
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:276
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:59
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:246
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:65
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:66
@ UNIT_STATE_ATTACK_PLAYER
Definition: UnitDefines.h:163
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:230
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3276
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:857
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:580
DiminishingReturnsType
Definition: SharedDefines.h:3249
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3251
@ DRTYPE_ALL
Definition: SharedDefines.h:3252
bool isWorldBoss() const
Definition: Creature.h:123
bool IsInEvadeMode() const
Definition: Creature.h:137
uint32 flags_extra
Definition: CreatureData.h:249
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5692
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14945
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14971
uint32 GetCombatTimer() const
Definition: Unit.h:1042
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12772
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17187
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:825
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:14985
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14811
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:1763
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13672
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1181
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5659
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12687
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12856
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10181
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13817
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1173
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2747
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:574
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2525

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_REFLECT_SPELLS, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3257{
3258 // Apply additional spell effects to target
3260 if (m_preCastSpell)
3261 {
3262 // Paladin immunity shields
3263 if (m_preCastSpell == 61988)
3264 {
3265 // Cast Forbearance
3266 m_caster->CastSpell(unit, 25771, true);
3267 // Cast Avenging Wrath Marker
3268 unit->CastSpell(unit, 61987, true);
3269 }
3270
3271 // Avenging Wrath
3272 if (m_preCastSpell == 61987)
3273 // Cast the serverside immunity shield marker
3274 m_caster->CastSpell(unit, 61988, true);
3275
3276 // Fearie Fire (Feral) - damage
3277 if( m_preCastSpell == 60089 )
3278 m_caster->CastSpell(unit, m_preCastSpell, true);
3279 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3280 // Blizz seems to just apply aura without bothering to cast
3282 }
3283
3284 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3285 // this is executed after spell proc spells on target hit
3286 // spells are triggered for each hit spell target
3287 // info confirmed with retail sniffs of permafrost and shadow weaving
3288 if (!m_hitTriggerSpells.empty())
3289 {
3290 int _duration = 0;
3291 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3292 {
3293 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3294 {
3295 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3296 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3297
3298 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3299 // set duration of current aura to the triggered spell
3300 if (i->triggeredSpell->GetDuration() == -1)
3301 {
3302 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3303 {
3304 // get duration from aura-only once
3305 if (!_duration)
3306 {
3307 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3308 _duration = aur ? aur->GetDuration() : -1;
3309 }
3310 triggeredAur->SetDuration(_duration);
3311 }
3312 }
3313 }
3314 }
3315 }
3316
3317 // trigger linked auras remove/apply
3319 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3320 {
3321 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3322 if (*i < 0)
3323 {
3324 unit->RemoveAurasDueToSpell(-(*i));
3325 }
3326 else
3327 {
3328 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3329 }
3330 }
3331}
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
bool roll_chance_i(int chance)
Definition: Random.h:59
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5535
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18791
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:754

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4232{
4234 return;
4235
4236 if (!gameObjTarget)
4237 return;
4238
4239 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4240 switch (action)
4241 {
4242 case GameObjectActions::AnimateCustom0:
4243 case GameObjectActions::AnimateCustom1:
4244 case GameObjectActions::AnimateCustom2:
4245 case GameObjectActions::AnimateCustom3:
4246 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4247 break;
4248 case GameObjectActions::Disturb: // What's the difference with Open?
4249 case GameObjectActions::Open:
4250 if (Unit* unitCaster = m_caster->ToUnit())
4251 gameObjTarget->Use(unitCaster);
4252 break;
4253 case GameObjectActions::OpenAndUnlock:
4254 if (Unit* unitCaster = m_caster->ToUnit())
4255 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4256 [[fallthrough]];
4257 case GameObjectActions::Unlock:
4258 case GameObjectActions::Lock:
4259 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4260 break;
4261 case GameObjectActions::Close:
4262 case GameObjectActions::Rebuild:
4264 break;
4265 case GameObjectActions::Despawn:
4267 break;
4268 case GameObjectActions::MakeInert:
4269 case GameObjectActions::MakeActive:
4270 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4271 break;
4272 case GameObjectActions::CloseAndLock:
4275 break;
4276 case GameObjectActions::Destroy:
4277 if (Unit* unitCaster = m_caster->ToUnit())
4278 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4279 break;
4280 case GameObjectActions::UseArtKit0:
4281 case GameObjectActions::UseArtKit1:
4282 case GameObjectActions::UseArtKit2:
4283 case GameObjectActions::UseArtKit3:
4284 {
4285 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4286
4287 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4288
4289 uint32 artKitValue = 0;
4290 if (templateAddon)
4291 artKitValue = templateAddon->artKits[artKitIndex];
4292
4293 if (artKitValue == 0)
4294 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4295 else
4296 gameObjTarget->SetGoArtKit(artKitValue);
4297
4298 break;
4299 }
4300 case GameObjectActions::None:
4301 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4302 break;
4303 default:
4304 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4305 break;
4306 }
4307}
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
GameObjectActions
Definition: GameObject.h:77
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1604
#define LOG_FATAL(filterType__,...)
Definition: Log.h:152
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1429
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1443
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2150
void ResetDoorOrButton()
Definition: GameObject.cpp:1419
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:933
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:912
void Use(Unit *user)
Definition: GameObject.cpp:1479
Definition: GameObjectData.h:665
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:671
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899

References Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, GameObject::DespawnOrUnsummon(), effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), GameObject::Use(), and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5746{
5748 return;
5749
5750 if (!m_caster->IsPlayer())
5751 return;
5752
5753 Player* player = m_caster->ToPlayer();
5754
5756 return;
5757
5758 // needed later
5760
5761 uint32 count = damage;
5762 if (count == 0) count = 1;
5763 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5764 {
5765 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5766 {
5767 if (m_spellInfo->Id == 45529)
5768 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5769 continue;
5770 player->SetRuneCooldown(j, 0);
5771 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5772 --count;
5773 }
5774 }
5775
5776 // Blood Tap
5777 if (m_spellInfo->Id == 45529 && count > 0)
5778 {
5779 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5780 {
5781 // Check if both runes are on cd as that is the only time when this needs to come into effect
5782 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5783 {
5784 // Should always update the rune with the lowest cd
5785 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5786 l++;
5787 player->SetRuneCooldown(l, 0);
5788 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5789 --count;
5790 }
5791 else
5792 break;
5793 }
5794 }
5795
5796 // Empower rune weapon
5797 if (m_spellInfo->Id == 47568)
5798 {
5799 // Need to do this just once
5800 if (effIndex != 0)
5801 return;
5802
5803 for (uint32 i = 0; i < MAX_RUNES; ++i)
5804 {
5805 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5806 {
5807 player->SetRuneCooldown(i, 0);
5808 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5809 }
5810 }
5811 }
5812
5813 // is needed to push through to the client that the rune is active
5814 //player->ResyncRunes(MAX_RUNES);
5815 m_caster->CastSpell(m_caster, 47804, true);
5816}
@ RUNE_FROST
Definition: Player.h:411
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2493
uint8 GetRunesState() const
Definition: Player.h:2482
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2494
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2483

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6138{
6140 return;
6141
6142 if (!unitTarget)
6143 return;
6144
6145 if (Player* player = unitTarget->ToPlayer())
6146 {
6147 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6148 }
6149}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4069{
4071 {
4072 return;
4073 }
4074
4075 if (!unitTarget || damage <= 0)
4076 {
4077 return;
4078 }
4079
4081}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:530

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4651{
4653 {
4654 return;
4655 }
4656
4657 if (!unitTarget || !unitTarget->IsAlive())
4658 {
4659 return;
4660 }
4661
4663
4665}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2732
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5107

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2696{
2698 return;
2699
2700 if (!m_caster->IsPlayer())
2701 return;
2702
2703 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2704 int32 duration = m_spellInfo->GetDuration();
2705 // Caster not in world, might be spell triggered from aura removal
2706 if (!m_caster->IsInWorld())
2707 return;
2708
2709 // Remove old farsight if exist
2710 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2711
2712 DynamicObject* dynObj = new DynamicObject(true);
2713 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2714 {
2715 delete dynObj;
2716 return;
2717 }
2718
2719 dynObj->SetDuration(duration);
2720 dynObj->SetCasterViewpoint(updateViewerVisibility);
2721}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:205
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:233
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:99
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:638

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2766{
2768 return;
2769
2770 if (!unitTarget->IsPlayer())
2771 return;
2772
2773 // not scale value for item based reward (/10 value expected)
2774 if (m_CastItem)
2775 {
2776 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2777 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2779 return;
2780 }
2781
2782 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2783 if (damage <= 50)
2784 {
2786 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2787 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2788 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2789 }
2790 else
2791 {
2792 //maybe we have correct honor_gain in damage already
2793 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2794 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2796 }
2797}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:38
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:6021

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1308{
1310 return;
1311
1312 if (!m_spellAura || !unitTarget)
1313 return;
1316}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4310{
4312 return;
4313
4315 return;
4316
4317 Player* player = m_caster->ToPlayer();
4318
4319 // glyph sockets level requirement
4320 uint8 minLevel = 0;
4321 switch (m_glyphIndex)
4322 {
4323 case 0:
4324 case 1:
4325 minLevel = 15;
4326 break;
4327 case 2:
4328 minLevel = 50;
4329 break;
4330 case 3:
4331 minLevel = 30;
4332 break;
4333 case 4:
4334 minLevel = 70;
4335 break;
4336 case 5:
4337 minLevel = 80;
4338 break;
4339 }
4340 if (minLevel && m_caster->GetLevel() < minLevel)
4341 {
4343 return;
4344 }
4345
4346 // apply new one
4347 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4348 {
4349 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4350 {
4351 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4352 {
4353 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4354 {
4356 return; // glyph slot mismatch
4357 }
4358 }
4359
4360 // remove old glyph aura
4361 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4362 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4363 {
4364 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4365
4366 // Removed any triggered auras
4367 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4368 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4369 {
4370 Aura* aura = iter->second;
4371 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4372 {
4373 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4374 {
4375 player->RemoveOwnedAura(iter);
4376 continue;
4377 }
4378 }
4379 ++iter;
4380 }
4381
4382 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4383 }
4384
4385 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4387 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4388 player->SendTalentsInfoData(false);
4389 }
4390 }
4391}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:148
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:676
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1126
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1124
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14370
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3019
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1747
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1738
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1739
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4670
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
AuraMap & GetOwnedAuras()
Definition: Unit.h:1257
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1029

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6271{
6273 return;
6274
6275 if (!unitTarget)
6276 return;
6277
6278 Player* player = unitTarget->ToPlayer();
6279 if (!player)
6280 {
6281 return;
6282 }
6283
6284 WorldLocation homeLoc;
6285 uint32 areaId = player->GetAreaId();
6286
6287 if (m_spellInfo->Effects[effIndex].MiscValue)
6288 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6289
6290 if (m_targets.HasDst())
6291 homeLoc.WorldRelocate(*destTarget);
6292 else
6293 {
6294 homeLoc = player->GetWorldLocation();
6295 }
6296
6297 player->SetHomebind(homeLoc, areaId);
6298
6299 // binding
6300 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6301 data << float(homeLoc.GetPositionX());
6302 data << float(homeLoc.GetPositionY());
6303 data << float(homeLoc.GetPositionZ());
6304 data << uint32(homeLoc.GetMapId());
6305 data << uint32(areaId);
6306 player->SendDirectMessage(&data);
6307
6308 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6309 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6310 // zone update
6311 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6312 data << m_caster->GetGUID();
6313 data << uint32(areaId);
6314 player->SendDirectMessage(&data);
6315}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:251
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:281
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5649
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4911

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4677{
4679 return;
4680
4681 if (m_caster->IsPlayer())
4682 m_caster->ToPlayer()->SetCanBlock(true);
4683}
void SetCanBlock(bool value)
Definition: Player.cpp:13082

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6198{
6200 return;
6201
6202 if (!m_caster->IsPlayer())
6203 return;
6204
6205 Player* p_caster = m_caster->ToPlayer();
6206 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6207 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6208
6209 for (; n_buttons; --n_buttons, ++button_id)
6210 {
6211 ActionButton const* ab = p_caster->GetActionButton(button_id);
6212 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6213 continue;
6214
6217 uint32 spell_id = ab->GetAction();
6218 if (!spell_id)
6219 continue;
6220
6221 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6222 if (!spellInfo)
6223 continue;
6224
6225 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6226 continue;
6227
6229 continue;
6230
6231 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6232 if (m_caster->GetPower(POWER_MANA) < cost)
6233 continue;
6234
6236 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6237 }
6238}
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
Definition: Player.h:253
uint32 GetAction() const
Definition: Player.h:261
ActionButtonType GetType() const
Definition: Player.h:260
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5595
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3859

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4896{
4898 {
4899 if (!unitTarget)
4900 return;
4901
4902 ObjectGuid targetGUID = ObjectGuid::Empty;
4903 Player* player = m_caster->ToPlayer();
4904 if (player)
4905 {
4906 // charge changes fall time
4908
4910 {
4911 targetGUID = unitTarget->GetGUID();
4912 }
4913 }
4914
4915 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4916 // Spell is not using explicit target - no generated path
4917 if (!m_preGeneratedPath)
4918 {
4920 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4921 }
4922 else
4923 {
4924 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4925 }
4926
4927 if (player)
4928 {
4929 sScriptMgr->AnticheatSetUnderACKmount(player);
4930 }
4931 }
4932}
#define SPEED_CHARGE
Definition: MotionMaster.h:107
@ EVENT_CHARGE
Definition: SharedDefines.h:3311
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2818
Definition: Position.h:28
float m_positionZ
Definition: Position.h:58
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:197
float m_positionX
Definition: Position.h:56
float m_positionY
Definition: Position.h:57
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2313
MotionMaster * GetMotionMaster()
Definition: Unit.h:1605
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:667

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1765{
1767 return;
1768
1769 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1770 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1771}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5135
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1635

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1774{
1776 return;
1777
1778 if (!unitTarget)
1779 return;
1780
1781 Player* player = unitTarget->ToPlayer();
1782 if (!player)
1783 {
1784 return;
1785 }
1786
1787 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1788
1789 if (itemId)
1790 DoCreateItem(effIndex, itemId);
1791
1792 // special case: fake item replaced by generate using spell_loot_template
1794 {
1795 if (itemId)
1796 {
1797 if (!player->HasItemCount(itemId))
1798 return;
1799
1800 // remove reagent
1801 uint32 count = 1;
1802 player->DestroyItemCount(itemId, count, true);
1803
1804 // create some random items
1806 }
1807 else
1808 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1809 }
1811}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition: Player.cpp:13437
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3136
bool IsLootCrafting() const
Definition: SpellInfo.cpp:924

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1814{
1816 return;
1817
1818 if (!unitTarget)
1819 return;
1820
1821 Player* player = unitTarget->ToPlayer();
1822 if (!player)
1823 {
1824 return;
1825 }
1826
1827 // create some random items
1830}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5819{
5821 return;
5822
5824 return;
5825
5826 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5827 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5828 if (!pet)
5829 return;
5830
5831 // add to world
5832 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5833
5834 // unitTarget has pet now
5835 unitTarget->SetMinion(pet, true);
5836
5837 pet->InitTalentForLevel();
5838
5839 if (unitTarget->IsPlayer())
5840 {
5843 }
5844}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2225
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:507
void PetSpellInitialize()
Definition: Player.cpp:9425
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10625
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17279
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:555

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5230{
5232 return;
5233
5234 int32 mana = 0;
5235 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5236 {
5237 if (!m_caster->m_SummonSlot[slot])
5238 continue;
5239
5241 if (totem && totem->IsTotem())
5242 {
5243 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5244 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5245 if (spellInfo)
5246 {
5247 mana += spellInfo->ManaCost;
5249 }
5250 totem->ToTotem()->UnSummon();
5251 }
5252 }
5253 ApplyPct(mana, damage);
5254 if (mana)
5255 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5256}
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
T ApplyPct(T &base, U pct)
Definition: Util.h:73
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:1742
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1211
uint32 GetCreateMana() const
Definition: Unit.h:1384
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1411
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3314
uint32 ManaCostPercentage
Definition: SpellInfo.h:367
uint32 ManaCost
Definition: SpellInfo.h:363

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5847{
5849 return;
5850
5851 if (!unitTarget)
5852 return;
5853
5854 Player* player = unitTarget->ToPlayer();
5855 if (!player)
5856 {
5857 return;
5858 }
5859
5860 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5861 if (sTaxiNodesStore.LookupEntry(nodeid))
5862 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5863}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:152

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4447{
4449 return;
4450
4452 return;
4453
4454 if (Player* caster = m_caster->ToPlayer())
4455 {
4456 caster->UpdateCraftSkill(m_spellInfo->Id);
4457 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4458 }
4459
4460 // item will be removed at disenchanting end
4461}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:84

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4533{
4535 return;
4536
4537 if (!unitTarget || !unitTarget->IsPet())
4538 return;
4539
4540 Pet* pet = unitTarget->ToPet();
4541
4542 ExecuteLogEffectUnsummonObject(effIndex, pet);
4544}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:884
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5153

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2545{
2547 return;
2548
2549 if (!unitTarget)
2550 return;
2551
2552 // Create dispel mask by dispel type
2553 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2554 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2555
2556 DispelChargesList dispel_list;
2557 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2558 if (dispel_list.empty())
2559 return;
2560
2561 // Ok if exist some buffs for dispel try dispel it
2562 uint32 failCount = 0;
2563 DispelChargesList success_list;
2564 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2565 // dispel N = damage buffs (or while exist buffs for dispel)
2566 for (int32 count = 0; count < damage && !dispel_list.empty();)
2567 {
2568 // Random select buff for dispel
2569 DispelChargesList::iterator itr = dispel_list.begin();
2570 std::advance(itr, urand(0, dispel_list.size() - 1));
2571
2572 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2573 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2574 if (!chance)
2575 {
2576 dispel_list.erase(itr);
2577 continue;
2578 }
2579 else
2580 {
2581 if (roll_chance_i(chance))
2582 {
2583 bool alreadyListed = false;
2584 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2585 {
2586 if (successItr->first->GetId() == itr->first->GetId())
2587 {
2588 ++successItr->second;
2589 alreadyListed = true;
2590 }
2591 }
2592 if (!alreadyListed)
2593 success_list.push_back(std::make_pair(itr->first, 1));
2594 --itr->second;
2595 if (itr->second <= 0)
2596 dispel_list.erase(itr);
2597 }
2598 else
2599 {
2600 if (!failCount)
2601 {
2602 // Failed to dispell
2603 dataFail << m_caster->GetGUID(); // Caster GUID
2604 dataFail << unitTarget->GetGUID(); // Victim GUID
2605 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2606 }
2607 ++failCount;
2608 dataFail << uint32(itr->first->GetId()); // Spell Id
2609 }
2610 ++count;
2611 }
2612 }
2613
2614 if (failCount)
2615 m_caster->SendMessageToSet(&dataFail, true);
2616
2617 // put in combat
2620
2621 if (success_list.empty())
2622 return;
2623
2624 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2625 // Send packet header
2626 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2627 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2628 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2629 dataSuccess << uint8(0); // not used
2630 dataSuccess << uint32(success_list.size()); // count
2631 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2632 {
2633 // Send dispelled spell info
2634 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2635 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2636 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2637 }
2638 m_caster->SendMessageToSet(&dataSuccess, true);
2639
2640 // On success dispel
2641 // Devour Magic
2643 {
2644 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2645 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2646 // Glyph of Felhunter
2647 if (Unit* owner = m_caster->GetOwner())
2648 if (owner->GetAura(56249))
2649 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2650 }
2651}
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition: SpellMgr.h:40
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3533
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ SMSG_DISPEL_FAILED
Definition: Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition: Opcodes.h:665
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition: Unit.cpp:5559
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition: Unit.cpp:4907
uint32 GetCategory() const
Definition: SpellInfo.cpp:870

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5135{
5137 return;
5138
5139 if (!unitTarget)
5140 return;
5141
5142 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5143
5144 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5145
5146 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5147 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5148 {
5149 Aura* aura = itr->second;
5151 continue;
5153 {
5154 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5155 {
5156 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5157
5158 // spell only removes 1 bleed effect do not continue
5159 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5160 {
5161 break;
5162 }
5163 }
5164 }
5165 }
5166
5167 for (; dispel_list.size(); dispel_list.pop())
5168 {
5169 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5170 }
5171
5172 // put in combat
5175}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4741
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1182

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2668{
2670 return;
2671
2672 // Check for possible target
2673 if (!unitTarget || unitTarget->IsEngaged())
2674 return;
2675
2676 // target must be OK to do this
2678 return;
2679
2682}
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:20441
bool IsEngaged() const
Definition: Unit.h:1029
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition: MotionMaster.cpp:795

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2654{
2656 return;
2657
2659}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:686

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4084{
4086 return;
4087
4088 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4089 return;
4090
4091 Player* caster = m_caster->ToPlayer();
4092 Player* target = unitTarget->ToPlayer();
4093
4094 // caster or target already have requested duel
4095 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4096 return;
4097
4098 // Players can only fight a duel in zones with this flag
4099 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4100 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4101 {
4102 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4103 return;
4104 }
4105
4106 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4107 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4108 {
4109 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4110 return;
4111 }
4112
4113 //CREATE DUEL FLAG OBJECT
4114 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4115 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4116
4117 Map* map = m_caster->GetMap();
4118 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4119 map, m_caster->GetPhaseMask(),
4123 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4124 {
4125 delete pGameObj;
4126 return;
4127 }
4128
4131 int32 duration = m_spellInfo->GetDuration();
4132 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4133 pGameObj->SetSpellId(m_spellInfo->Id);
4134
4135 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4136
4137 m_caster->AddGameObject(pGameObj);
4138 map->AddToMap(pGameObj, true);
4139 //END
4140
4141 // Send request
4142 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4143 data << pGameObj->GetGUID();
4144 data << caster->GetGUID();
4145 caster->GetSession()->SendPacket(&data);
4146 target->GetSession()->SendPacket(&data);
4147
4148 // create duel-info
4149 bool isMounted = (GetSpellInfo()->Id == 62875);
4150 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4151 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4152
4153 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4154 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4155
4156 sScriptMgr->OnPlayerDuelRequest(target, caster);
4157}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1028
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1303
void SetSpellId(uint32 id)
Definition: GameObject.h:177
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
uint32 GetPhaseMask() const
Definition: Object.h:446
float GetOrientation() const
Definition: Position.h:120
PlayerSocial * GetSocial()
Definition: Player.h:1141
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:840
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6133
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5147
uint32 flags
Definition: DBCStructure.h:524

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
667{
669 return;
670
672 return;
673
674 // selection by spell family
676 {
678 {
679 switch (m_spellInfo->Id)
680 {
681 // Trial of the Champion, Trample
682 case 67866:
683 {
685 unitTarget->CastSpell(unitTarget, 67867, false);
686 return;
687 }
688 // Trial of the Champion, Hammer of the Righteous
689 case 66867:
690 {
691 if( !unitTarget )
692 return;
693 if( unitTarget->HasAura(66940) )
694 m_caster->CastSpell(unitTarget, 66903, true);
695 else
696 m_caster->CastSpell(unitTarget, 66904, true);
697 return;
698 }
699 case 17731:
700 case 69294:
701 {
703 return;
704
708 trigger->CastSpell(trigger, 17731, false);
709
710 return;
711 }
712 // HoL, Arc Weld
713 case 59086:
714 {
716 m_caster->CastSpell(m_caster, 59097, true);
717
718 return;
719 }
720 }
721 break;
722 }
724 switch (m_spellInfo->Id)
725 {
726 case 31789: // Righteous Defense (step 1)
727 {
728 if (!unitTarget)
729 return;
730 // not empty (checked), copy
732
733 // remove invalid attackers
734 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
735 if (!(*aItr)->IsValidAttackTarget(m_caster))
736 aItr = attackers.erase(aItr);
737 else
738 ++aItr;
739
740 // selected from list 3
741 uint32 maxTargets = std::min<uint32>(3, attackers.size());
742 for (uint32 i = 0; i < maxTargets; ++i)
743 {
744 Unit::AttackerSet::iterator aItr = attackers.begin();
745 std::advance(aItr, urand(0, attackers.size() - 1));
746 m_caster->CastSpell((*aItr), 31790, true);
747 attackers.erase(aItr);
748 }
749
750 return;
751 }
752 }
753 break;
755 // Hunger for Blood
756 if( m_spellInfo->Id == 51662 )
757 {
758 m_caster->CastSpell(m_caster, 63848, true);
759 return;
760 }
761 break;
762 }
763
764 // pet auras
765 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
766 {
767 m_caster->AddPetAura(petSpell);
768 return;
769 }
770
771 // normal DB scripted effect
772 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
774
775 if (gameObjTarget)
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
778 }
779 else if (unitTarget && unitTarget->IsCreature())
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
782 }
783 else if (itemTarget)
784 {
785 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
786 }
787}
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:57
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:47
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3528
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3538
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3536
uint8 GetGoAnimProgress() const
Definition: GameObject.h:210
time_t GetRespawnTime() const
Definition: GameObject.h:184
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition: Object.cpp:2352
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:17225
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:632
AttackerSet const & getAttackers() const
Definition: Unit.h:724
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:33
Definition: SpellMgr.h:470

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5259{
5261 return;
5262
5263 if (!unitTarget)
5264 return;
5265
5266 Player* player = unitTarget->ToPlayer();
5267 if (!player)
5268 {
5269 return;
5270 }
5271
5272 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5273
5274 // -1 means all player equipped items and -2 all items
5275 if (slot < 0)
5276 {
5277 player->DurabilityPointsLossAll(damage, (slot < -1));
5279 return;
5280 }
5281
5282 // invalid slot value
5283 if (slot >= INVENTORY_SLOT_BAG_END)
5284 return;
5285
5286 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5287 {
5288 player->DurabilityPointsLoss(item, damage);
5289 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5290 }
5291}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:700
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:670
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:464
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4703
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4729
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5121

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5294{
5296 return;
5297
5298 if (!unitTarget)
5299 return;
5300
5301 Player* player = unitTarget->ToPlayer();
5302 if (!player)
5303 {
5304 return;
5305 }
5306
5307 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5308
5309 // FIXME: some spells effects have value -1/-2
5310 // Possibly its mean -1 all player equipped items and -2 all items
5311 if (slot < 0)
5312 {
5313 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5314 return;
5315 }
5316
5317 // invalid slot value
5318 if (slot >= INVENTORY_SLOT_BAG_END)
5319 return;
5320
5321 if (damage <= 0)
5322 return;
5323
5324 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5325 player->DurabilityLoss(item, float(damage) / 100.0f);
5326}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4659
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4685

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4394{
4396 return;
4397
4398 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4399 if (!unitTarget)
4400 return;
4401
4402 Player* item_owner = unitTarget->ToPlayer();
4403 if (!item_owner)
4404 {
4405 return;
4406 }
4407
4409 if (!item)
4410 return;
4411
4412 // must be equipped
4413 if (!item->IsEquipped())
4414 return;
4415
4416 if (m_spellInfo->Effects[effIndex].MiscValue)
4417 {
4418 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4419 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4420 if (!duration)
4421 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4422 if (!duration)
4423 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4424
4425 // Xinef: Venomhide poison, no other spell uses this effect...
4426 if (m_spellInfo->Id == 14792)
4427 duration = 5 * MINUTE * IN_MILLISECONDS;
4428
4429 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4430 if (!pEnchant)
4431 return;
4432
4433 // Always go to temp enchantment slot
4435
4436 // Enchantment will not be applied if a different one already exists
4437 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4438 return;
4439
4440 // Apply the temporary enchantment
4441 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4442 item_owner->ApplyEnchantment(item, slot, true);
4443 }
4444}
EnchantmentSlot
Definition: Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:690
bool IsEquipped() const
Definition: Item.cpp:790
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:921
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4319
uint32 charges
Definition: DBCStructure.h:1843

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2812{
2814 return;
2815
2816 if (!m_caster->IsPlayer())
2817 return;
2818 if (!itemTarget)
2819 return;
2820
2821 Player* p_caster = m_caster->ToPlayer();
2822
2823 // Handle vellums
2825 {
2826 // destroy one vellum from stack
2827 uint32 count = 1;
2828 p_caster->DestroyItemCount(itemTarget, count, true);
2829 unitTarget = p_caster;
2830 // and add a scroll
2831 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2832 itemTarget = nullptr;
2833 m_targets.SetItemTarget(nullptr);
2834 }
2835 else
2836 {
2837 // do not increase skill if vellum used
2839 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2840
2841 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2842 if (!enchant_id)
2843 return;
2844
2845 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2846 if (!pEnchant)
2847 return;
2848
2849 // item can be in trade slot and have owner diff. from caster
2850 Player* item_owner = itemTarget->GetOwner();
2851 if (!item_owner)
2852 return;
2853
2854 // remove old enchanting before applying new if equipped
2856
2858
2859 // add new enchanting if equipped
2861
2862 item_owner->RemoveTradeableItem(itemTarget);
2864 }
2865}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1265
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4154
void SetItemTarget(Item *item)
Definition: Spell.cpp:329

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2868{
2870 return;
2871
2872 if (!m_caster->IsPlayer())
2873 return;
2874 if (!itemTarget)
2875 return;
2876
2877 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2878 if (!enchant_id)
2879 return;
2880
2881 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2882 if (!pEnchant)
2883 return;
2884
2885 // support only enchantings with add socket in this slot
2886 {
2887 bool add_socket = false;
2888 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2889 {
2890 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2891 {
2892 add_socket = true;
2893 break;
2894 }
2895 }
2896 if (!add_socket)
2897 {
2898 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2900 return;
2901 }
2902 }
2903
2904 // item can be in trade slot and have owner diff. from caster
2905 Player* item_owner = itemTarget->GetOwner();
2906 if (!item_owner)
2907 return;
2908
2909 // remove old enchanting before applying new if equipped
2911
2913
2914 // add new enchanting if equipped
2916
2917 item_owner->RemoveTradeableItem(itemTarget);
2919}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2922{
2924 return;
2925
2926 if (!m_caster->IsPlayer())
2927 return;
2928
2929 Player* p_caster = m_caster->ToPlayer();
2930
2931 // Rockbiter Weapon apply to both weapon
2932 if (!itemTarget)
2933 return;
2935 {
2936 uint32 spell_id = 0;
2937
2938 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2939 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2940 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2941 switch (damage)
2942 {
2943 // Rank 1
2944 case 2:
2945 spell_id = 36744;
2946 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2947 // Rank 2
2948 case 4:
2949 spell_id = 36753;
2950 break; // 0% [ 7% == 4, 14% == 4]
2951 case 5:
2952 spell_id = 36751;
2953 break; // 20%
2954 // Rank 3
2955 case 6:
2956 spell_id = 36754;
2957 break; // 0% [ 7% == 6, 14% == 6]
2958 case 7:
2959 spell_id = 36755;
2960 break; // 20%
2961 // Rank 4
2962 case 9:
2963 spell_id = 36761;
2964 break; // 0% [ 7% == 6]
2965 case 10:
2966 spell_id = 36758;
2967 break; // 14%
2968 case 11:
2969 spell_id = 36760;
2970 break; // 20%
2971 default:
2972 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2973 return;
2974 }
2975
2976 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2977 if (!spellInfo)
2978 {
2979 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
2980 return;
2981 }
2982
2983 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
2984 {
2985 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
2986 {
2987 if (item->IsFitToSpellRequirements(m_spellInfo))
2988 {
2989 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
2990 SpellCastTargets targets;
2991 targets.SetItemTarget(item);
2992 spell->prepare(&targets);
2993 }
2994 }
2995 }
2996 return;
2997 }
2998 if (!itemTarget)
2999 return;
3000
3001 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3002
3003 if (!enchant_id)
3004 {
3005 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3006 return;
3007 }
3008
3009 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3010 if (!pEnchant)
3011 {
3012 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3013 return;
3014 }
3015
3016 // select enchantment duration
3017 uint32 duration;
3018
3019 // rogue family enchantments exception by duration
3020 if (m_spellInfo->Id == 38615)
3021 duration = 1800; // 30 mins
3022 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3024 duration = 3600; // 1 hour
3025 // shaman family enchantments
3027 duration = 1800; // 30 mins
3028 // other cases with this SpellVisual already selected
3029 else if (m_spellInfo->SpellVisual[0] == 215)
3030 duration = 1800; // 30 mins
3031 // some fishing pole bonuses except Glow Worm which lasts full hour
3032 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3033 duration = 600; // 10 mins
3034 // shaman rockbiter enchantments
3035 else if (m_spellInfo->SpellVisual[0] == 0)
3036 duration = 1800; // 30 mins
3037 else if (m_spellInfo->Id == 29702)
3038 duration = 300; // 5 mins
3039 else if (m_spellInfo->Id == 37360)
3040 duration = 300; // 5 mins
3041 // default case
3042 else
3043 duration = 3600; // 1 hour
3044
3045 // item can be in trade slot and have owner diff. from caster
3046 Player* item_owner = itemTarget->GetOwner();
3047 if (!item_owner)
3048 return;
3049
3050 // remove old enchanting before applying new if equipped
3052
3053 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3054
3055 // add new enchanting if equipped
3057
3058 item_owner->RemoveTradeableItem(itemTarget);
3060}
WeaponAttackType
Definition: Unit.h:208
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3539
Definition: Spell.h:109
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3468
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:379

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1867{
1869 return;
1870
1871 if (!unitTarget)
1872 return;
1873 if (!unitTarget->IsAlive())
1874 return;
1875
1876 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1877 return;
1878
1879 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1880
1883 return;
1884
1885 if (unitTarget->GetMaxPower(power) == 0)
1886 return;
1887
1888 // Some level depends spells
1889 int level_multiplier = 0;
1890 int level_diff = 0;
1891 switch (m_spellInfo->Id)
1892 {
1893 case 9512: // Restore Energy
1894 level_diff = m_caster->GetLevel() - 40;
1895 level_multiplier = 2;
1896 break;
1897 case 24571: // Blood Fury
1898 level_diff = m_caster->GetLevel() - 60;
1899 level_multiplier = 10;
1900 break;
1901 case 24532: // Burst of Energy
1902 level_diff = m_caster->GetLevel() - 60;
1903 level_multiplier = 4;
1904 break;
1905 case 31930: // Judgements of the Wise
1906 case 63375: // Improved Stormstrike
1907 case 68082: // Glyph of Seal of Command
1909 break;
1910 case 48542: // Revitalize
1912 break;
1913 case 71132: // Glyph of Shadow Word: Pain
1914 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1915 break;
1916 default:
1917 break;
1918 }
1919
1920 if (level_diff > 0)
1921 damage -= level_multiplier * level_diff;
1922
1923 if (damage < 0)
1924 return;
1925
1927
1928 // Mad Alchemist's Potion
1929 if (m_spellInfo->Id == 45051)
1930 {
1931 // find elixirs on target
1932 bool guardianFound = false;
1933 bool battleFound = false;
1935 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1936 {
1937 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1938 if (!guardianFound)
1940 guardianFound = true;
1941 if (!battleFound)
1943 battleFound = true;
1944 if (battleFound && guardianFound)
1945 break;
1946 }
1947
1948 // get all available elixirs by mask and spell level
1949 std::set<uint32> availableElixirs;
1950 if (!guardianFound)
1951 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1952 if (!battleFound)
1953 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1954 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1955 {
1956 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1957 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1958 availableElixirs.erase(itr++);
1959 else
1960 ++itr;
1961 }
1962
1963 if (!availableElixirs.empty())
1964 {
1965 // cast random elixir on target
1967 }
1968 }
1969}
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:337
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:657
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3541
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:133
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11211

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1972{
1974 return;
1975
1976 if (!unitTarget)
1977 return;
1978 if (!unitTarget->IsAlive())
1979 return;
1980
1981 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1982 return;
1983
1984 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1985
1987 return;
1988
1989 uint32 maxPower = unitTarget->GetMaxPower(power);
1990 if (maxPower == 0)
1991 return;
1992
1993 uint32 gain = CalculatePct(maxPower, damage);
1995}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
303{
305 return;
306
307 if (!unitTarget || !unitTarget->IsAlive())
308 return;
309
310 if (unitTarget->IsPlayer())
312 else
313 {
315
316 uint32 absorb = dmgInfo.GetAbsorb();
317 uint32 resist = dmgInfo.GetResist();
318 uint32 envDamage = dmgInfo.GetDamage();
319
320 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
321 damage = envDamage;
322
324 }
325}
@ DAMAGE_FIRE
Definition: Player.h:839
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:754

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4500{
4502 return;
4503
4504 Player* player = m_caster->ToPlayer();
4505 if (!player)
4506 return;
4507
4508 Item* foodItem = itemTarget;
4509 if (!foodItem)
4510 return;
4511
4512 Pet* pet = player->GetPet();
4513 if (!pet)
4514 return;
4515
4516 if (!pet->IsAlive())
4517 return;
4518
4519 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4520 if (benefit <= 0)
4521 return;
4522
4523 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4524
4525 uint32 count = 1;
4526 player->DestroyItemCount(foodItem, count, true);
4528
4529 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4530}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5141

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
1001{
1003 return;
1004
1005 if (!unitTarget)
1006 return;
1007
1008 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1009
1010 // normal case
1011 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1012
1013 if (!spellInfo)
1014 {
1015 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1016 return;
1017 }
1018
1019 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1020 {
1021 switch (m_spellInfo->Id)
1022 {
1023 case 52588: // Skeletal Gryphon Escape
1024 case 48598: // Ride Flamebringer Cue
1026 break;
1027 case 52463: // Hide In Mine Car
1028 case 52349: // Overtake
1029 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1030 return;
1031 case 72378: // Blood Nova
1032 case 73058: // Blood Nova
1033 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1034 break;
1035 }
1036 }
1037
1038 CustomSpellValues values;
1039 // set basepoints for trigger with value effect
1041 {
1042 // maybe need to set value only when basepoints == 0?
1046 }
1047
1048 SpellCastTargets targets;
1049 targets.SetUnitTarget(m_caster);
1050
1051 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1052}
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:116
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:114
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:918
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:919
Definition: SpellDefines.h:163
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:165

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4756{
4758 return;
4759
4760 // xinef: clear focus
4762
4764 data << m_caster->GetGUID();
4765
4767 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4768 Cell::VisitWorldObjects(m_caster, notifier, dist);
4769
4770 // xinef: we should also force pets to remove us from current target
4771 Unit::AttackerSet attackerSet;
4772 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4773 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4774 attackerSet.insert(*itr);
4775
4776 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4777 (*itr)->AttackStop();
4778
4779 // Xinef: Mirror images code Initialize Images
4780 if (m_spellInfo->Id == 58836)
4781 {
4782 std::vector<Unit*> images;
4783 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4784 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4785 images.push_back(*itr);
4786
4787 if (images.empty())
4788 return;
4789
4790 UnitList targets;
4791 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4794 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4795 {
4796 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4797 continue;
4798
4799 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4800 {
4801 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4802 {
4803 SpellInfo const* si = spell->GetSpellInfo();
4804 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4805 {
4806 Creature* c = (*iter)->ToCreature();
4807 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4808 continue;
4809 }
4810
4811 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4812 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4813 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4814 {
4815 // at least one effect truly targets an unit, interrupt the spell
4816 interrupt = true;
4817 break;
4818 }
4819
4820 if (interrupt)
4821 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4822 }
4823 }
4824 }
4825 }
4826}
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
std::list< Unit * > UnitList
Definition: Unit.h:76
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2734
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3157
uint32 rank
Definition: CreatureData.h:209
ControlSet m_Controlled
Definition: Unit.h:1210
void SendClearTarget()
Definition: Unit.cpp:20240
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:207
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:193
Definition: GridNotifiers.h:133
Definition: GridNotifiers.h:423
Definition: GridNotifiers.h:861

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5891{
5893 return;
5894
5895 if (!gameObjTarget)
5896 return;
5897
5898 Unit* caster = m_originalCaster;
5899 if (!caster)
5900 return;
5901
5902 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5904 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5905 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5907}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2277
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:9979
Definition: DBCStructure.h:939
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:951

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5921{
5923 return;
5924
5926 return;
5927
5930}
GameObjectDestructibleState
Definition: SharedDefines.h:1626
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2340

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1461{
1463 return;
1464
1465 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1466 {
1467 // Try to get original caster
1469
1470 // Skip if m_originalCaster not available
1471 if (!caster)
1472 return;
1473
1474 int32 addhealth = damage;
1475
1476 // Vessel of the Naaru (Vial of the Sunwell trinket)
1477 if (m_spellInfo->Id == 45064)
1478 {
1479 // Amount of heal - depends from stacked Holy Energy
1480 int damageAmount = 0;
1481 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1482 {
1483 damageAmount += aurEff->GetAmount();
1485 }
1486
1487 addhealth += damageAmount;
1488 }
1489 // Swiftmend - consumes Regrowth or Rejuvenation
1491 {
1493 // find most short by duration
1494 AuraEffect* forcedTargetAura = nullptr;
1495 AuraEffect* targetAura = nullptr;
1496 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1497 {
1498 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1499 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1500 {
1501 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1502 {
1503 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1504 forcedTargetAura = *i;
1505 }
1506 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1507 targetAura = *i;
1508 }
1509 }
1510
1511 if (forcedTargetAura)
1512 targetAura = forcedTargetAura;
1513
1514 if (!targetAura)
1515 {
1516 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1517 return;
1518 }
1519
1520 int32 tickheal = targetAura->GetAmount();
1521 if (Unit* auraCaster = targetAura->GetCaster())
1522 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1523
1524 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1525 //It is said that talent bonus should not be included
1526
1527 int32 tickcount = 0;
1528 // Rejuvenation
1529 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1530 tickcount = 4;
1531 // Regrowth
1532 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1533 tickcount = 6;
1534
1535 addhealth += tickheal * tickcount;
1536
1537 // Glyph of Swiftmend
1538 if (!caster->HasAura(54824))
1539 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1540
1541 //addhealth += tickheal * tickcount;
1542 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1543 }
1544 // Death Pact - return pct of max health to caster
1546 {
1547 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1548 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1549 }
1550 else if (m_spellInfo->Id != 33778) // not lifebloom
1551 {
1552 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1553 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1554 }
1555
1556 // Implemented this way as there is no other way to do it currently (that I know :P)...
1557 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1558 {
1560 {
1561 m_damage = 0;
1562 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1563 return;
1564 }
1565 }
1566
1567 m_damage -= addhealth;
1568 }
1569}
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ DOT
Definition: Unit.h:250
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3535
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3543
@ AURA_STATE_SWIFTMEND
Definition: SharedDefines.h:1307
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:298
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:791
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
uint32 GetId() const
Definition: SpellAuraEffects.cpp:432
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
int32 GetAmount() const
Definition: SpellAuraEffects.h:64
uint32 TargetAuraState
Definition: SpellInfo.h:340

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3663{
3665 return;
3666
3667 if (!unitTarget || !unitTarget->IsAlive())
3668 return;
3669
3670 int32 addhealth = 0;
3671
3672 // damage == 0 - heal for caster max health
3673 if (damage == 0)
3674 addhealth = m_caster->GetMaxHealth();
3675 else
3676 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3677
3678 m_healing += addhealth;
3679}
uint32 GetMaxHealth() const
Definition: Unit.h:783

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), Unit::IsAlive(), m_caster, m_healing, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1607{
1609 return;
1610
1611 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1612 return;
1613
1616
1617 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1618
1619 // xinef: handled in spell.cpp
1620 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1621
1622 m_damage += damage;
1623 // get max possible damage, don't count overkill for heal
1624 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1625
1626 //if (m_caster->IsAlive())
1627 //{
1628 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1629 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1630
1631 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1632 //}
1633}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11731
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:11555

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4464{
4466 return;
4467
4468 if (!unitTarget)
4469 return;
4470
4471 Player* player = unitTarget->ToPlayer();
4472 if (!player)
4473 {
4474 return;
4475 }
4476
4477 uint8 currentDrunk = player->GetDrunkValue();
4478 int32 drunkMod = damage;
4479
4480 if (drunkMod == 0)
4481 return;
4482
4483 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4484 // In addition, we would not want currentDrunk to become more than 100.
4485 // So before adding the values, let's check that everything is fine.
4486 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4487 currentDrunk = 100;
4488 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4489 currentDrunk = 0;
4490 else
4491 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4492
4493 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4494
4495 if (currentDrunk == 100 && roll_chance_i(25))
4496 player->CastSpell(player, 67468, false); // Drunken Vomit
4497}
uint8 GetDrunkValue() const
Definition: Player.h:2148
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:971

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
279{
281 return;
282
283 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
284 return;
285
286 if (unitTarget->IsPlayer())
288 return;
289
290 if (m_caster == unitTarget) // prevent interrupt message
291 finish();
292
293 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
294 data << m_caster->GetGUID();
295 data << unitTarget->GetGUID();
296 data << uint32(m_spellInfo->Id);
297 m_caster->SendMessageToSet(&data, true);
298
300}
@ CHEAT_GOD
Definition: Player.h:999
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
@ SMSG_SPELLINSTAKILLLOG
Definition: Opcodes.h:845
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:797

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3682{
3684 return;
3685
3686 if (!unitTarget || !unitTarget->IsAlive())
3687 return;
3688
3690 // also exist case: apply cooldown to interrupted cast only and to all spells
3691 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3693 {
3695 {
3696 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3697 // check if we can interrupt spell
3698 if ((spell->getState() == SPELL_STATE_CASTING
3699 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3703 {
3704 if (m_originalCaster)
3705 {
3707 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3708 }
3709 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3711 }
3712 }
3713 }
3714}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:38
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:30
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:543
CurrentSpellTypes
Definition: Unit.h:536
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4027
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14794
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:1391
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5114
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:354
uint32 InterruptFlags
Definition: SpellInfo.h:352

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1074{
1076 return;
1077
1078 if (m_caster->IsInFlight())
1079 return;
1080
1081 if (!unitTarget)
1082 return;
1083
1084 float speedXY, speedZ;
1085 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1086 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1087
1088 if (m_caster->IsPlayer())
1089 {
1090 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1091 }
1092}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:227
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1157

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1095{
1097 return;
1098
1099 if (m_caster->IsInFlight())
1100 return;
1101
1102 if (!m_targets.HasDst() || m_caster->GetVehicle())
1103 return;
1104
1105 // Init dest coordinates
1106 float x, y, z;
1107 destTarget->GetPosition(x, y, z);
1108 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1109 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1110 return;
1111
1112 float speedXY, speedZ;
1113 float dist = m_caster->GetExactDist2d(x, y);
1114 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1115
1116 // Override, calculations are incorrect
1117 if (m_spellInfo->Id == 49376) // feral charge
1118 {
1119 speedXY = pow(speedZ * 10, 8);
1121
1122 if (Player* player = m_caster->ToPlayer())
1123 {
1124 player->SetCanTeleport(true);
1125 }
1126
1127 if (m_caster->IsPlayer())
1128 {
1129 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1130 }
1131
1132 return;
1133 }
1134
1135 if (m_spellInfo->Id == 57604) // death grip
1136 {
1137 speedZ = 3.0f;
1138 speedXY = 50.0f;
1139 }
1140
1141 // crash fix?
1142 if (speedXY < 1.0f)
1143 speedXY = 1.0f;
1144
1145 if (Player* player = m_caster->ToPlayer())
1146 {
1147 player->SetCanTeleport(true);
1148 }
1149 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1150
1151 if (m_caster->IsPlayer())
1152 {
1153 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1154 }
1155}
#define INVALID_HEIGHT
Definition: Map.h:165
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5683{
5685 return;
5686
5687 if (!unitTarget)
5688 return;
5689
5691 if (!player)
5692 {
5693 return;
5694 }
5695
5696 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5697 if (!creatureEntry)
5698 {
5699 if (m_spellInfo->Id == 42793) // Burn Body
5700 creatureEntry = 24008; // Fallen Combatant
5701 }
5702
5703 if (creatureEntry)
5704 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5705}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12682

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5669{
5671 return;
5672
5673 if (!unitTarget)
5674 return;
5675
5677 {
5678 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5679 }
5680}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4960{
4962 return;
4963
4964 if (!unitTarget)
4965 return;
4966
4967 // Xinef: allow entry specific spells to skip those checks
4968 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4969 {
4971 return;
4972
4973 if (unitTarget->GetVehicle())
4974 return;
4975
4976 if (Creature* creatureTarget = unitTarget->ToCreature())
4977 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4978 return;
4979 }
4980
4981 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
4983 return;
4984
4985 // Instantly interrupt non melee spells being casted
4988
4989 float ratio = 0.1f;
4990 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
4991 float speedz = float(damage) * ratio;
4992 if (speedxy <= 0.1f && speedz <= 0.1f)
4993 return;
4994
4995 float x, y;
4996 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
4997 {
4998 if (m_targets.HasDst())
4999 destTarget->GetPosition(x, y);
5000 else
5001 return;
5002 }
5003 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5004 {
5005 m_caster->GetPosition(x, y);
5006 }
5007
5008 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5009
5010 if (unitTarget->IsPlayer())
5011 {
5012 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5013 }
5014}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:922
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2632
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2628
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4094
uint32 GetCreatureType() const
Definition: Unit.cpp:15120
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19071

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4686{
4688 return;
4689
4690 if (!unitTarget || unitTarget->IsInFlight())
4691 return;
4692
4693 if (!m_targets.HasDst())
4694 return;
4695
4696 Position dstpos = destTarget->GetPosition();
4698}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19909

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5017{
5019 return;
5020
5021 if (!unitTarget)
5022 return;
5023
5024 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5025 float speedz = damage / 10.0f;
5026 //1891: Disengage
5028
5029 if (m_caster->IsPlayer())
5030 {
5031 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5032 }
5033
5034 // xinef: changes fall time
5035 if (m_caster->IsPlayer())
5037}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19442

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3233{
3235 return;
3236
3237 if (!unitTarget)
3238 return;
3239
3240 if (unitTarget->ToPlayer())
3241 {
3242 EffectLearnSpell(effIndex);
3243 return;
3244 }
3245 Pet* pet = unitTarget->ToPet();
3246 if (!pet)
3247 return;
3248
3249 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3250 if (!learn_spellproto)
3251 return;
3252
3253 pet->learnSpell(learn_spellproto->Id);
3255 pet->GetOwner()->PetSpellInitialize();
3256}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1912
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2519

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2750{
2752 return;
2753
2754 if (!unitTarget->IsPlayer())
2755 return;
2756
2757 if (damage < 0)
2758 return;
2759
2760 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2761 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2762 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2763}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5459
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5273

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2520{
2522 return;
2523
2524 if (!unitTarget)
2525 return;
2526
2527 if (!unitTarget->IsPlayer())
2528 {
2529 if (unitTarget->ToPet())
2530 EffectLearnPetSpell(effIndex);
2531 return;
2532 }
2533
2534 Player* player = unitTarget->ToPlayer();
2535
2536 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2537 player->learnSpell(spellToLearn);
2538
2539 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2540 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2541}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3271
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3232

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5496{
5498 return;
5499
5500 if (!m_caster->IsPlayer())
5501 return;
5502
5503 Player* p_caster = m_caster->ToPlayer();
5505 return;
5506
5507 if (itemTarget->GetCount() < 5)
5508 return;
5509
5510 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5511 {
5512 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5513 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5514 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5515 }
5516
5518}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:97
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7730
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:719

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5329{
5331 return;
5332
5333 if (!unitTarget)
5334 return;
5335
5337}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:1488

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
243{
244 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
245}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2064{
2066 return;
2067
2068 if (!m_caster->IsPlayer())
2069 {
2070 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2071 return;
2072 }
2073
2074 Player* player = m_caster->ToPlayer();
2075
2076 uint32 lockId = 0;
2077 ObjectGuid guid;
2078
2079 // Get lockId
2080 if (gameObjTarget)
2081 {
2082 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2083 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2084 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2085 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2086 {
2087 //CanUseBattlegroundObject() already called in CheckCast()
2088 // in battleground check
2089 if (Battleground* bg = player->GetBattleground())
2090 {
2091 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2092 return;
2093 }
2094 }
2095 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2096 {
2097 //CanUseBattlegroundObject() already called in CheckCast()
2098 // in battleground check
2099 if (Battleground* bg = player->GetBattleground())
2100 {
2101 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2102 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2103 return;
2104 }
2105 }
2106 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2107 {
2110 {
2112 }
2113 return;
2114 }
2116 // handle outdoor pvp object opening, return true if go was registered for handling
2117 // these objects must have been spawned by outdoorpvp!
2118 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2119 return;
2120 lockId = goInfo->GetLockId();
2121 guid = gameObjTarget->GetGUID();
2122 }
2123 else if (itemTarget)
2124 {
2125 lockId = itemTarget->GetTemplate()->LockID;
2126 guid = itemTarget->GetGUID();
2127 }
2128 else
2129 {
2130 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2131 return;
2132 }
2133
2134 SkillType skillId = SKILL_NONE;
2135 int32 reqSkillValue = 0;
2136 int32 skillValue;
2137
2138 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2139 if (res != SPELL_CAST_OK)
2140 {
2141 SendCastResult(res);
2142 return;
2143 }
2144
2145 if (gameObjTarget)
2146 SendLoot(guid, LOOT_SKINNING);
2147 else if (itemTarget)
2148 {
2150 if (Player* itemOwner = itemTarget->GetOwner())
2151 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2152 }
2153
2154 // not allow use skill grow at item base open
2155 if (!m_CastItem && skillId != SKILL_NONE)
2156 {
2157 // update skill if really known
2158 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2159 {
2160 if (gameObjTarget)
2161 {
2162 // Allow one skill-up until respawned
2163 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2164 {
2166 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2167 }
2168
2169 }
2170 else if (itemTarget)
2171 {
2172 // Do one skill-up
2173 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2174 }
2175 }
2176 }
2178}
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ ITEM_CHANGED
Definition: Item.h:210
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:111
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:114
@ LOOT_SKINNING
Definition: LootMgr.h:86
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:103
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1561
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1584
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3487
Unit * GetOwner() const
Definition: GameObject.cpp:1238
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3068
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3074
LootState getLootState() const
Definition: GameObject.h:225
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2442
Definition: GameObjectData.h:32
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:511
uint32 noDamageImmune
Definition: GameObjectData.h:49
struct GameObjectTemplate::@227::@230 button
uint32 losOK
Definition: GameObjectData.h:65
struct GameObjectTemplate::@227::@238 goober
uint32 GetLockId() const
Definition: GameObjectData.h:428
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:715
Definition: Object.h:100
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5129
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:1997

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4668{
4670 return;
4671
4672 if (m_caster->IsPlayer())
4673 m_caster->ToPlayer()->SetCanParry(true);
4674}
void SetCanParry(bool value)
Definition: Player.cpp:13073

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1833{
1835 return;
1836
1837 if (!m_spellAura)
1838 {
1840 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1841
1842 // Caster not in world, might be spell triggered from aura removal
1843 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1844 return;
1845 DynamicObject* dynObj = new DynamicObject(false);
1846 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1847 {
1848 delete dynObj;
1849 return;
1850 }
1851
1853 {
1854 m_spellAura = aura;
1857 }
1858 else
1859 return;
1860 }
1861
1864}
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1638
DynamicObject * GetDynobjOwner() const
Definition: SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6099{
6101 return;
6102
6103 if (!unitTarget)
6104 return;
6105
6106 Player* player = unitTarget->ToPlayer();
6107 if (!player)
6108 {
6109 return;
6110 }
6111
6112 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6113
6114 if (!sSoundEntriesStore.LookupEntry(soundid))
6115 {
6116 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6117 return;
6118 }
6119
6121}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition: MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6152{
6154 return;
6155
6156 if (!unitTarget)
6157 return;
6158
6159 Player* player = unitTarget->ToPlayer();
6160 if (!player)
6161 {
6162 return;
6163 }
6164
6165 switch (m_spellInfo->Id)
6166 {
6167 case 58730: // Restricted Flight Area
6168 case 58600: // Restricted Flight Area
6170 break;
6171 default:
6172 break;
6173 }
6174
6175 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6176
6177 if (!sSoundEntriesStore.LookupEntry(soundId))
6178 {
6179 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6180 return;
6181 }
6182
6183 player->PlayDirectSound(soundId, player);
6184}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:753
Definition: Chat.h:39
void SendNotification(std::string_view str)
Definition: Chat.cpp:107
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2887

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1419{
1421 return;
1422
1423 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1424 return;
1425
1426 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1427
1429 return;
1430
1431 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1432 if (m_spellInfo->Id == 8129)
1433 {
1436 damage = std::min(damage, maxDamage);
1437
1438 // Remove fear
1440 }
1441
1442 int32 power = damage;
1443 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1444 if (PowerType == POWER_MANA)
1445 power -= unitTarget->GetSpellCritDamageReduction(power);
1446
1447 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1448
1449 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1450 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1451
1452 // add log data before multiplication (need power amount, not damage)
1453 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1454
1455 newDamage = int32(newDamage * dmgMultiplier);
1456
1457 m_damage += newDamage;
1458}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14089
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:931
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5098

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1340{
1342 return;
1343
1344 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1345 return;
1346
1347 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1348
1350 return;
1351
1352 // add spell damage bonus
1355
1356 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1357 int32 power = damage;
1358 if (PowerType == POWER_MANA)
1359 power -= unitTarget->GetSpellCritDamageReduction(power);
1360
1361 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1362
1363 float gainMultiplier = 0.0f;
1364
1365 // Don`t restore from self drain
1366 if (m_caster != unitTarget)
1367 {
1368 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1369
1370 int32 gain = int32(newDamage * gainMultiplier);
1371
1373 }
1374 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1375}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2290{
2292 return;
2293
2294 if (!m_caster->IsPlayer())
2295 return;
2296 Player* p_target = m_caster->ToPlayer();
2297
2299 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2300 {
2301 p_target->AddWeaponProficiency(subClassMask);
2303 }
2304 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2305 {
2306 p_target->AddArmorProficiency(subClassMask);
2308 }
2309}
uint32 GetArmorProficiency() const
Definition: Player.h:1353
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10058
uint32 GetWeaponProficiency() const
Definition: Player.h:1352
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1351
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1350
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2662{
2664 EffectNULL(effIndex);
2665}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:242

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5102{
5104 return;
5105
5106 if (!unitTarget)
5107 return;
5108
5109 Position pos;
5110 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5111 {
5112 if (m_targets.HasDst())
5113 pos.Relocate(*destTarget);
5114 else
5115 return;
5116 }
5117 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5118 {
5119 // Xinef: Increase Z position a little bit, should protect from falling through textures
5121 }
5122
5123 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5124 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5125
5126 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5127
5128 if (unitTarget->IsPlayer())
5129 {
5130 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5131 }
5132}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:923
double gravity
Definition: MovementUtil.cpp:24
void Relocate(float x, float y)
Definition: Position.h:73

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5040{
5042 return;
5043
5044 if (!unitTarget)
5045 return;
5046
5047 Player* player = unitTarget->ToPlayer();
5048 if (!player)
5049 {
5050 return;
5051 }
5052
5053 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5054
5055 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5056
5057 if (!quest)
5058 return;
5059
5060 // Player has never done this quest
5061 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5062 return;
5063
5064 // remove all quest entries for 'entry' from quest log
5065 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5066 {
5067 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5068 if (logQuest == quest_id)
5069 {
5070 player->SetQuestSlot(slot, 0);
5071
5072 // we ignore unequippable quest items in this case, it's still be equipped
5073 player->TakeQuestSourceItem(logQuest, false);
5074
5075 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5076 {
5077 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5078 player->UpdatePvPState();
5079 }
5080 }
5081 }
5082
5083 player->RemoveRewardedQuest(quest_id);
5084 player->RemoveActiveQuest(quest_id, false);
5085}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:360
bool IsInHostileArea
Definition: Player.h:361
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2489
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1390
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1474
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1478
PvPInfo pvpInfo
Definition: Player.h:1824
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1357
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1489
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1424
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1507
Definition: QuestDef.h:209
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:220

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4727{
4729 return;
4730
4731 if (!unitTarget)
4732 return;
4733
4734 Player* player = unitTarget->ToPlayer();
4735 if (!player)
4736 {
4737 return;
4738 }
4739
4740 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4741 if (questId)
4742 {
4743 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4744 if (!quest)
4745 return;
4746
4747 uint16 logSlot = player->FindQuestSlot(questId);
4748 if (logSlot < MAX_QUEST_LOG_SIZE)
4749 player->AreaExploredOrEventHappens(questId);
4750 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4751 player->CompleteQuest(questId); // quest not in log - for internal use
4752 }
4753}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1776
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:597
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1785

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), Player::CompleteQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5708{
5710 return;
5711
5712 if (!unitTarget)
5713 return;
5714
5715 if (Player* player = unitTarget->ToPlayer())
5716 {
5717 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5718 }
5719}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5722{
5724 return;
5725
5726 if (!unitTarget)
5727 return;
5728
5729 Player* player = unitTarget->ToPlayer();
5730 if (!player)
5731 return;
5732
5733 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5734 {
5735 if (!player->CanTakeQuest(quest, false))
5736 return;
5737
5738 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5739 player->AddQuestAndCheckCompletion(quest, player);
5740
5741 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5742 }
5743}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
PlayerMenu * PlayerTalkClass
Definition: Player.h:2216

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6241{
6243 return;
6244
6245 if (!unitTarget || !unitTarget->IsPlayer())
6246 return;
6247
6248 Player* player = m_caster->ToPlayer();
6249
6250 if (!player)
6251 return;
6252
6253 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6254
6255 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6256 if (!pProto)
6257 {
6258 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6259 return;
6260 }
6261
6262 if (Item* pItem = player->GetItemByEntry(item_id))
6263 {
6264 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6265 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6266 pItem->SetState(ITEM_CHANGED, player);
6267 }
6268}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5882{
5884 return;
5885
5886 if (unitTarget)
5888}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:1687

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6187{
6189 return;
6190
6191 if (!unitTarget)
6192 return;
6193 // there may be need of specifying casterguid of removed auras
6194 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6195}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6087{
6089 return;
6090
6091 if (!unitTarget || !unitTarget->IsCreature() ||
6093 return;
6094
6096}
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4701{
4703 return;
4704
4705 if (!unitTarget)
4706 return;
4707
4708 Player* player = unitTarget->ToPlayer();
4709 if (!player)
4710 {
4711 return;
4712 }
4713
4714 float repChange = static_cast<float>(damage);
4715
4716 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4717
4718 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4719 if (!factionEntry)
4720 return;
4721
4722 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4723 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4724}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:245
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5826
ReputationMgr & GetReputationMgr()
Definition: Player.h:2102
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:118
Definition: DBCStructure.h:907

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4619{
4621 return;
4622
4623 if (!unitTarget)
4624 return;
4625
4626 if (!unitTarget)
4627 return;
4628
4629 Player* target = unitTarget->ToPlayer();
4630 if (!target)
4631 {
4632 return;
4633 }
4634
4635 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4636 return;
4637
4638 if (target->isResurrectRequested()) // already have one active request
4639 return;
4640
4641 uint32 health = target->CountPctFromMaxHealth(damage);
4643
4644 ExecuteLogEffectResurrect(effIndex, target);
4645
4647 SendResurrectRequest(target);
4648}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1793
bool isResurrectRequested() const
Definition: Player.h:1805
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5159
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5221

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5178{
5180 return;
5181
5182 if (damage < 0)
5183 return;
5184
5185 Player* player = m_caster->ToPlayer();
5186 if (!player)
5187 {
5188 return;
5189 }
5190
5191 Pet* pet = player->GetPet();
5192 if (!pet)
5193 {
5194 // Position passed to SummonPet is irrelevant with current implementation,
5195 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5196 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5197 return;
5198 }
5199
5201 if (pet->IsAlive())
5202 {
5203 return;
5204 }
5205
5206 // Reposition the pet's corpse before reviving so as not to grab aggro
5207 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5208 float x, y, z; // Will be used later to reposition the pet if we have one
5209 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5210 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5211 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5214 pet->setDeathState(DeathState::Alive);
5215 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5217 pet->SetDisplayId(pet->GetNativeDisplayId());
5218
5219 // xinef: restore movement
5220 if (auto ci = pet->GetCharmInfo())
5221 {
5222 ci->SetIsAtStay(false);
5223 ci->SetIsFollowing(false);
5224 }
5225
5227}
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
@ UNIT_STATE_POSSESSED
Definition: UnitDefines.h:165
@ UNIT_STATE_ALL_STATE
Definition: UnitDefines.h:199
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3120
float GetFollowAngle() const override
Definition: TemporarySummon.h:82
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2696
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition: Pet.cpp:631
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition: Pet.cpp:2421
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8886
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:666
void SetHealth(uint32 val)
Definition: Unit.cpp:15416
uint32 GetNativeDisplayId() const
Definition: Unit.h:1513
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:827

References Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4003{
4005 return;
4006
4007 if (!unitTarget)
4008 return;
4009
4011 {
4013 // Xinef: replaced with CombatStop(false)
4016
4017 // Night Elf: Shadowmeld only resets threat temporarily
4018 if (m_spellInfo->Id != 59646)
4020
4021 if (unitTarget->IsPlayer())
4022 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4023 }
4024 else
4025 {
4026 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4027 unitTarget->CombatStop(true);
4028 }
4029
4030 UnitList targets;
4031 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4034 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4035 {
4036 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4037 continue;
4038
4040 {
4041 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4042 {
4043 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4044 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4045 {
4046 Creature* c = (*iter)->ToCreature();
4047 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4048 continue;
4049 }
4050 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4051 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4052 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4053 {
4054 // at least one effect truly targets an unit, interrupt the spell
4055 interrupt = true;
4056 break;
4057 }
4058 if (interrupt)
4059 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4060 }
4061 }
4062 }
4063
4064 // Xinef: Set last sanctuary time
4066}
#define CURRENT_MAX_SPELL
Definition: Unit.h:544
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10381
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition: Unit.cpp:10429
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition: Unit.cpp:10348
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:122

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
328{
330 return;
331
332 if (unitTarget && unitTarget->IsAlive())
333 {
334 bool apply_direct_bonus = true;
336 {
338 {
339 // Meteor like spells (divided damage to targets)
341 {
342 uint32 count = 0;
343 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
344 if (ihit->effectMask & (1 << effIndex))
345 ++count;
346
347 damage /= count; // divide to all targets
348 }
349 break;
350 }
352 {
353 // Shield Slam
354 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
355 {
356 uint8 level = m_caster->GetLevel();
357 // xinef: shield block should increase the limit
358 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
359 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
360
361 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
362 }
363 // Victory Rush
364 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
366 // Shockwave
367 else if (m_spellInfo->Id == 46968)
368 {
370 if (pct > 0)
372 break;
373 }
374 break;
375 }
377 {
378 // Incinerate Rank 1 & 2
379 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
380 {
381 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
382 // Check aura state for speed but aura state set not only for Immolate spell
384 {
386 damage += damage / 4;
387 }
388 }
389 // Conflagrate - consumes Immolate or Shadowflame
391 {
392 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
393
395 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
396 {
397 // for caster applied auras only
398 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
399 (*i)->GetCasterGUID() != m_caster->GetGUID())
400 continue;
401
402 // Immolate
403 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
404 {
405 aura = *i; // it selected always if exist
406 break;
407 }
408
409 // Shadowflame
410 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
411 aura = *i; // remember but wait possible Immolate as primary priority
412 }
413
414 // found Immolate or Shadowflame
415 if (aura)
416 {
417 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
418 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
419 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
420 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
421
422 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
423
424 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
425 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
426
427 apply_direct_bonus = false;
428 // Glyph of Conflagrate
429 if (!m_caster->HasAura(56235))
431
432 break;
433 }
434 }
435 // Shadow Bite
436 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
437 {
438 if (m_caster->IsCreature() && m_caster->IsPet())
439 {
440 if (Player* owner = m_caster->GetOwner()->ToPlayer())
441 {
442 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
443 {
444 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
445 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
446 }
447 }
448 }
449 }
450 break;
451 }
453 {
454 // Improved Mind Blast (Mind Blast in shadow form bonus)
455 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
456 {
458 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
459 {
460 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
461 ((*i)->GetSpellInfo()->SpellIconID == 95))
462 {
463 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
464 if (roll_chance_i(chance))
465 // Mind Trauma
466 m_caster->CastSpell(unitTarget, 48301, true, 0);
467 break;
468 }
469 }
470 }
471 break;
472 }
474 {
475 // Ferocious Bite
476 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
477 {
478 // converts each extra point of energy into ($f1+$AP/410) additional damage
480 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
481 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
482 damage += int32(energy * multiple);
484 }
485 // Wrath
486 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
487 {
488 // Improved Insect Swarm
489 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
491 AddPct(damage, aurEff->GetAmount());
492 }
493 break;
494 }
496 {
497 // Envenom
498 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
499 {
500 if (Player* player = m_caster->ToPlayer())
501 {
502 // consume from stack dozes not more that have combo-points
503 if (uint32 combo = player->GetComboPoints())
504 {
505 // Lookup for Deadly poison (only attacker applied)
507 {
508 // count consumed deadly poison doses at target
509 bool needConsume = true;
510 uint32 spellId = aurEff->GetId();
511
512 uint32 doses = aurEff->GetBase()->GetStackAmount();
513 if (doses > combo)
514 doses = combo;
515
516 // Master Poisoner
517 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
518 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
519 {
520 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
521 {
522 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
523
524 if (chance && roll_chance_i(chance))
525 needConsume = false;
526
527 break;
528 }
529 }
530
531 if (needConsume)
532 for (uint32 i = 0; i < doses; ++i)
534
535 damage *= doses;
536 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
537 }
538
539 // Eviscerate and Envenom Bonus Damage (item set effect)
540 if (m_caster->HasAura(37169))
541 damage += combo * 40;
542 }
543 }
544 }
545 // Eviscerate
546 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
547 {
548 if (m_caster->IsPlayer())
549 {
550 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
551 {
553 damage += int32(ap * combo * 0.07f);
554
555 // Eviscerate and Envenom Bonus Damage (item set effect)
556 if (m_caster->HasAura(37169))
557 damage += combo * 40;
558 }
559 }
560 }
561 break;
562 }
564 {
565 //Gore
566 if (m_spellInfo->SpellIconID == 1578)
567 {
568 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
569 damage *= 2;
570 }
571 // Steady Shot
572 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
573 {
574 bool found = false;
575 // check dazed affect
577 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
578 {
579 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
580 {
581 found = true;
582 break;
583 }
584 }
585
587 if (found)
588 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
589
590 if (Player* caster = m_caster->ToPlayer())
591 {
592 // Add Ammo and Weapon damage plus RAP * 0.1
593 float dmg_min = 0.f;
594 float dmg_max = 0.f;
595 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
596 {
597 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
598 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
599 }
600
601 if (dmg_max == 0.0f && dmg_min > dmg_max)
602 {
603 damage += int32(dmg_min);
604 }
605 else
606 {
607 damage += irand(int32(dmg_min), int32(dmg_max));
608 }
609 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
610 }
611 }
612 break;
613 }
615 {
616 // Hammer of the Righteous
617 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
618 {
619 // Add main hand dps * effect[2] amount
620 if (Player* player = m_caster->ToPlayer())
621 {
622 float minTotal = 0.f;
623 float maxTotal = 0.f;
624 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
625 {
626 float tmpMin, tmpMax;
627 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
628 minTotal += tmpMin;
629 maxTotal += tmpMax;
630 }
631
632 float average = (minTotal + maxTotal) / 2;
635 }
636 break;
637 }
638 // Shield of Righteousness
639 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
640 {
641 uint8 level = m_caster->GetLevel();
642 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
643 if (m_caster->GetAuraEffect(64882, EFFECT_0))
644 block_value += 225;
645 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
646 break;
647 }
648 break;
649 }
650 }
651
652 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
653 {
654 // Xinef: protection
655 if (damage < 0)
656 damage = 0;
657
660 }
661
662 m_damage += damage;
663 }
664}
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:613
@ MINDAMAGE
Definition: Unit.h:135
@ MAXDAMAGE
Definition: Unit.h:136
@ FORM_SHADOW
Definition: UnitDefines.h:95
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_ENERGY
Definition: SharedDefines.h:272
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3534
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1306
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:15366
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition: Unit.cpp:14767
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4890
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:812
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:1319
uint8 GetStackAmount() const
Definition: SpellAuras.h:148

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3767{
3769 return;
3770
3772
3774 {
3776 {
3777 switch (m_spellInfo->Id)
3778 {
3779 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3780 case 22539:
3781 case 22972:
3782 case 22975:
3783 case 22976:
3784 case 22977:
3785 case 22978:
3786 case 22979:
3787 case 22980:
3788 case 22981:
3789 case 22982:
3790 case 22983:
3791 case 22984:
3792 case 22985:
3793 {
3794 if (!unitTarget || !unitTarget->IsAlive())
3795 return;
3796
3797 // Onyxia Scale Cloak
3798 if (unitTarget->HasAura(22683))
3799 return;
3800
3801 // Shadow Flame
3802 m_caster->CastSpell(unitTarget, 22682, true);
3803 return;
3804 }
3805 // Plant Warmaul Ogre Banner
3806 case 32307:
3807 if (Player* caster = m_caster->ToPlayer())
3808 {
3809 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3810 if (Creature* target = unitTarget->ToCreature())
3811 {
3812 target->setDeathState(DeathState::Corpse);
3813 target->RemoveCorpse();
3814 }
3815 }
3816 break;
3817 // SOTA defender teleport
3818 case 54640:
3819 {
3820 if (Player* player = unitTarget->ToPlayer())
3821 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3822 {
3823 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3824 {
3825 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3826 bg->DefendersPortalTeleport(dportal, player);
3827 }
3828 }
3829 return;
3830 }
3831 /*// Mug Transformation
3832 case 41931:
3833 {
3834 if (!m_caster->IsPlayer())
3835 return;
3836
3837 uint8 bag = 19;
3838 uint8 slot = 0;
3839 Item* item = nullptr;
3840
3841 while (bag) // 256 = 0 due to var type
3842 {
3843 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3844 if (item && item->GetEntry() == 38587)
3845 break;
3846
3847 ++slot;
3848 if (slot == 39)
3849 {
3850 slot = 0;
3851 ++bag;
3852 }
3853 }
3854 if (bag)
3855 {
3856 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3857 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3858 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3859 m_caster->CastSpell(m_caster, 42518, true);
3860 return;
3861 }
3862 break;
3863 }*/
3864 // Roll Dice - Decahedral Dwarven Dice
3865 case 47770:
3866 {
3867 char buf[128];
3868 const char* gender = "his";
3869 if (m_caster->getGender() > 0)
3870 gender = "her";
3871 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3872 m_caster->TextEmote(buf);
3873 break;
3874 }
3875 case 52173: // Coyote Spirit Despawn
3876 case 60243: // Blood Parrot Despawn
3879 return;
3880 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3881 {
3883 return;
3884
3886
3887 return;
3888 }
3889 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3890 {
3891 if (!m_caster->IsPlayer())
3892 return;
3893
3894 // Delete item from inventory at death
3896
3897 return;
3898 }
3899 case 58418: // Portal to Orgrimmar
3900 case 58420: // Portal to Stormwind
3901 {
3902 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3903 return;
3904
3905 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3906 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3907
3909 unitTarget->CastSpell(unitTarget, spellID, true);
3910
3911 return;
3912 }
3913 // Stoneclaw Totem
3914 case 55328: // Rank 1
3915 case 55329: // Rank 2
3916 case 55330: // Rank 3
3917 case 55332: // Rank 4
3918 case 55333: // Rank 5
3919 case 55335: // Rank 6
3920 case 55278: // Rank 7
3921 case 58589: // Rank 8
3922 case 58590: // Rank 9
3923 case 58591: // Rank 10
3924 {
3925 int32 basepoints0 = damage;
3926 // Cast Absorb on totems
3927 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
3928 {
3929 if (!unitTarget->m_SummonSlot[slot])
3930 continue;
3931
3933 if (totem && totem->IsTotem())
3934 {
3935 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3936 }
3937 }
3938 // Glyph of Stoneclaw Totem
3939 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3940 {
3941 basepoints0 *= aur->GetAmount();
3942 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3943 }
3944 break;
3945 }
3946 case 61263: // for item Intravenous Healing Potion (44698)
3947 {
3948 if( !m_caster || !unitTarget )
3949 return;
3950
3951 m_caster->CastSpell(m_caster, 61267, true);
3952 m_caster->CastSpell(m_caster, 61268, true);
3953 return;
3954 }
3955 }
3956 break;
3957 }
3958 case SPELLFAMILY_ROGUE:
3959 {
3960 switch( m_spellInfo->Id )
3961 {
3962 // Master of Subtlety
3963 case 31666:
3964 {
3965 if( !unitTarget )
3966 return;
3967
3968 Aura* mos = unitTarget->GetAura(31665);
3969 if( mos )
3970 {
3971 mos->SetMaxDuration(6000);
3972 mos->SetDuration(6000, true);
3973 }
3974
3975 break;
3976 }
3977 // Overkill
3978 case 58428:
3979 {
3980 if( !unitTarget )
3981 return;
3982
3983 Aura* overkill = unitTarget->GetAura(58427);
3984 if( overkill )
3985 {
3986 overkill->SetMaxDuration(20000);
3987 overkill->SetDuration(20000, true);
3988 }
3989
3990 break;
3991 }
3992 }
3993 break;
3994 }
3995 }
3996
3997 // normal DB scripted effect
3998 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4000}
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
@ BATTLEGROUND_SA
Definition: SharedDefines.h:3489
Class for manage Strand of Ancient battleground.
Definition: BattlegroundSA.h:456
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition: BattlegroundSA.cpp:585
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Definition: Creature.cpp:2173
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:282
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition: Object.cpp:2452
std::string const & GetName() const
Definition: Object.h:458
uint8 getGender() const
Definition: Unit.h:768
bool IsSummon() const
Definition: Unit.h:751
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition: Unit.cpp:21063

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4829{
4831 return;
4832
4833 if (!m_caster || m_caster->IsAlive())
4834 return;
4835 if (!m_caster->IsPlayer())
4836 return;
4837 if (!m_caster->IsInWorld())
4838 return;
4839
4840 uint32 health = 0;
4841 uint32 mana = 0;
4842
4843 // flat case
4844 if (damage < 0)
4845 {
4846 health = uint32(-damage);
4847 mana = m_spellInfo->Effects[effIndex].MiscValue;
4848 }
4849 // percent case
4850 else
4851 {
4855 }
4856
4857 Player* player = m_caster->ToPlayer();
4858 player->ResurrectPlayer(0.0f);
4859
4860 player->SetHealth(health);
4861 player->SetPower(POWER_MANA, mana);
4862 player->SetPower(POWER_RAGE, 0);
4863 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4864
4865 player->SpawnCorpseBones();
4866}
@ POWER_RAGE
Definition: SharedDefines.h:270
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4629
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4416
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15504

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1378{
1379 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1382 return;
1383
1384 WorldObject* target = nullptr;
1385
1386 // call events for object target if present
1388 {
1389 if (unitTarget)
1390 target = unitTarget;
1391 else if (gameObjTarget)
1392 target = gameObjTarget;
1393 }
1394 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1395 {
1396 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1397 // this check was requested by scripters, but it has some downsides:
1398 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1399 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1400 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1401 return;
1402 // some spells have no target entries in dbc and they use focus target
1403 if (focusObject)
1404 target = focusObject;
1406 }
1407
1408 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1409
1410 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1411 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1412 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1413 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1414
1415 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1416}
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
Definition: Object.h:405
ZoneScript * GetZoneScript() const
Definition: Object.h:537
Definition: ZoneScript.h:27

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5088{
5090 return;
5091
5092 if (!unitTarget)
5093 return;
5094
5095 if (Player* player = unitTarget->ToPlayer())
5096 {
5097 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5098 }
5099}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5521{
5523 return;
5524
5525 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5526}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4869{
4871 return;
4872
4873 if (!unitTarget->IsCreature())
4874 return;
4875 if (!m_caster->IsPlayer())
4876 return;
4877
4878 Creature* creature = unitTarget->ToCreature();
4879 int32 targetLevel = creature->GetLevel();
4880
4881 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4882
4886
4887 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4888
4889 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4890
4891 // Double chances for elites
4892 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4893}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:114
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:120

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5552{
5554 return;
5555
5556 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5557 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5558 return;
5559
5561}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7691

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, Player::RemovedInsignia(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6124{
6126 return;
6127
6128 if (!unitTarget)
6129 return;
6130
6131 if (Player* player = unitTarget->ToPlayer())
6132 {
6133 player->UpdateSpecCount(damage);
6134 }
6135}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5533{
5535 return;
5536
5537 /*
5538 if (!unitTarget->IsPlayer())
5539 return;
5540 if (!unitTarget->IsInWorld())
5541 return;
5542
5543 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5544 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5545 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5546 unitTarget->ToPlayer()->SpawnCorpseBones();
5547 */
5548}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5564{
5566 return;
5567
5568 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5569
5570 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5571 return;
5572
5573 DispelChargesList steal_list;
5574
5575 // Create dispel mask by dispel type
5576 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5577 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5578 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5579 {
5580 Aura* aura = itr->second;
5582 if (!aurApp)
5583 continue;
5584
5585 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5586 {
5587 // Need check for passive? this
5588 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5589 continue;
5590
5591 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5592 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5593 // Polymorph instead of 1 / (5 + 1) -> 16%.
5594 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5595 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5596 if (charges > 0)
5597 steal_list.push_back(std::make_pair(aura, charges));
5598 }
5599 }
5600
5601 if (steal_list.empty())
5602 return;
5603
5604 // Ok if exist some buffs for dispel try dispel it
5605 uint32 failCount = 0;
5606 DispelList success_list;
5607 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5608 // dispel N = damage buffs (or while exist buffs for dispel)
5609 for (int32 count = 0; count < damage && !steal_list.empty();)
5610 {
5611 // Random select buff for dispel
5612 DispelChargesList::iterator itr = steal_list.begin();
5613 std::advance(itr, urand(0, steal_list.size() - 1));
5614
5615 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5616 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5617 if (!chance)
5618 {
5619 steal_list.erase(itr);
5620 continue;
5621 }
5622 else
5623 {
5624 if (roll_chance_i(chance))
5625 {
5626 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5627 --itr->second;
5628 if (itr->second <= 0)
5629 steal_list.erase(itr);
5630 }
5631 else
5632 {
5633 if (!failCount)
5634 {
5635 // Failed to dispell
5636 dataFail << m_caster->GetGUID(); // Caster GUID
5637 dataFail << unitTarget->GetGUID(); // Victim GUID
5638 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5639 }
5640 ++failCount;
5641 dataFail << uint32(itr->first->GetId()); // Spell Id
5642 }
5643 ++count;
5644 }
5645 }
5646
5647 if (failCount)
5648 m_caster->SendMessageToSet(&dataFail, true);
5649
5650 if (success_list.empty())
5651 return;
5652
5653 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5654 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5655 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5656 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5657 dataSuccess << uint8(0); // not used
5658 dataSuccess << uint32(success_list.size()); // count
5659 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5660 {
5661 dataSuccess << uint32(itr->first); // Spell Id
5662 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5663 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5664 }
5665 m_caster->SendMessageToSet(&dataSuccess, true);
5666}
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2543
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:651
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:536
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:4971
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1082

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4160{
4162 return;
4163
4164 if (!m_caster->IsPlayer())
4165 return;
4166
4167 Player* target = m_caster->ToPlayer();
4168 if (target->IsInFlight())
4169 return;
4170
4171 // xinef: if player is dead - teleport to graveyard
4172 if (!target->IsAlive())
4173 {
4175 return;
4176
4177 // xinef: player is in corpse
4178 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4179 target->BuildPlayerRepop();
4180 target->RepopAtGraveyard();
4181 return;
4182 }
4183
4184 // xinef: no hearthstone in bag or on cooldown
4185 Item* hearthStone = target->GetItemByEntry(6948);
4186 if (!hearthStone || target->HasSpellCooldown(8690))
4187 {
4188 float o = rand_norm() * 2 * M_PI;
4189 Position pos = *target;
4190 target->MovePositionToFirstCollision(pos, 5.0f, o);
4191 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4192 return;
4193 }
4194
4195 // xinef: we have hearthstone not on cooldown, just use it
4197}
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
@ PLAYER_FLAGS_GHOST
Definition: Player.h:478
double rand_norm()
Definition: Random.cpp:77
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2855
void RepopAtGraveyard()
Definition: Player.cpp:4863
void BuildPlayerRepop()
Definition: Player.cpp:4367

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::HasAuraType(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_AURA_PREVENT_RESURRECTION, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2181{
2183 return;
2184
2185 if (!m_caster->IsPlayer())
2186 return;
2187
2188 Player* player = m_caster->ToPlayer();
2189
2190 // applied only to using item
2191 if (!m_CastItem)
2192 return;
2193
2194 // ... only to item in own inventory/bank/equip_slot
2195 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2196 return;
2197
2198 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2199 if (!newitemid)
2200 return;
2201
2202 uint16 pos = m_CastItem->GetPos();
2203
2204 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2205 if (!pNewItem)
2206 return;
2207
2208 // Client-side enchantment durations update
2210
2214
2216 {
2218 player->DurabilityLoss(pNewItem, lossPercent);
2219 }
2220
2221 if (player->IsInventoryPos(pos))
2222 {
2223 ItemPosCountVec dest;
2224 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2225 if (msg == EQUIP_ERR_OK)
2226 {
2227 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2228
2229 // prevent crash at access and unexpected charges counting with item update queue corrupt
2231 m_targets.SetItemTarget(nullptr);
2232
2233 m_CastItem = nullptr;
2235
2236 player->StoreItem(dest, pNewItem, true);
2237 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2238 return;
2239 }
2240 }
2241 else if (player->IsBankPos(pos))
2242 {
2243 ItemPosCountVec dest;
2244 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2245 if (msg == EQUIP_ERR_OK)
2246 {
2247 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2248
2249 // prevent crash at access and unexpected charges counting with item update queue corrupt
2251 m_targets.SetItemTarget(nullptr);
2252
2253 m_CastItem = nullptr;
2255
2256 player->BankItem(dest, pNewItem, true);
2257 return;
2258 }
2259 }
2260 else if (player->IsEquipmentPos(pos))
2261 {
2262 uint16 dest;
2263
2264 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2265
2266 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2267
2268 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2269 {
2271
2272 // prevent crash at access and unexpected charges counting with item update queue corrupt
2274 m_targets.SetItemTarget(nullptr);
2275
2276 m_CastItem = nullptr;
2278
2279 player->EquipItem(dest, pNewItem, true);
2280 player->AutoUnequipOffhandIfNeed();
2281 return;
2282 }
2283 }
2284
2285 // fail
2286 delete pNewItem;
2287}
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
uint8 GetSlot() const
Definition: Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1088
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:305
uint16 GetPos() const
Definition: Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:306
uint8 GetBagSlot() const
Definition: Item.cpp:785
void Clear()
Definition: ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1256
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1828
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1325
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1276
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4749
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2589
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3038
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1254
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12416
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2742
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2047
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1829
static bool IsBankPos(uint16 pos)
Definition: Player.h:1259

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4547{
4549 return;
4550
4551 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4552
4553 uint8 slot = 0;
4554 switch (m_spellInfo->Effects[effIndex].Effect)
4555 {
4557 slot = 0;
4558 break;
4560 slot = 1;
4561 break;
4563 slot = 2;
4564 break;
4566 slot = 3;
4567 break;
4568 default:
4569 return;
4570 }
4571
4572 if (m_caster)
4573 {
4574 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4575 if (guid)
4576 {
4577 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4578 {
4579 // Recast case - null spell id to make auras not be removed on object remove from world
4580 if (m_spellInfo->Id == gameObject->GetSpellId())
4581 gameObject->SetSpellId(0);
4582 m_caster->RemoveGameObject(gameObject, true);
4583 }
4584 m_caster->m_ObjectSlot[slot].Clear();
4585 }
4586 }
4587
4588 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4589
4590 float x, y, z;
4591 // If dest location if present
4592 if (m_targets.HasDst())
4593 destTarget->GetPosition(x, y, z);
4594 // Summon in random point all other units if location present
4595 else
4597
4598 Map* map = m_caster->GetMap();
4599 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4600 {
4601 delete pGameObj;
4602 return;
4603 }
4604
4605 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4606 int32 duration = m_spellInfo->GetDuration();
4607 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4608 pGameObj->SetSpellId(m_spellInfo->Id);
4609 m_caster->AddGameObject(pGameObj);
4610
4611 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4612
4613 map->AddToMap(pGameObj, true);
4614
4615 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4616}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:885
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:882
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:884
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:883
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:1412

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3717{
3719 return;
3720
3721 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3722
3723 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3724
3725 WorldObject* target = focusObject;
3726 if (!target)
3727 target = m_caster;
3728
3729 float x, y, z;
3730 if (m_targets.HasDst())
3731 destTarget->GetPosition(x, y, z);
3732 else
3734
3735 Map* map = target->GetMap();
3736
3737 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3738 {
3739 delete pGameObj;
3740 return;
3741 }
3742
3743 int32 duration = m_spellInfo->GetDuration();
3744
3745 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3746 pGameObj->SetSpellId(m_spellInfo->Id);
3747
3748 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3749
3750 // Wild object not have owner and check clickable by players
3751 map->AddToMap(pGameObj, true);
3752
3753 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3754 if (Player* player = m_caster->ToPlayer())
3755 if (Battleground* bg = player->GetBattleground())
3756 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3757
3758 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3759 {
3760 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3761 linkedTrap->SetSpellId(m_spellInfo->Id);
3762 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3763 }
3764}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1586
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ TEAM_HORDE
Definition: SharedDefines.h:761
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2735
GameobjectTypes GetGoType() const
Definition: GameObject.h:204

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3119{
3121 return;
3122
3123 if (!m_originalCaster)
3124 return;
3125
3126 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3127 int32 duration = m_spellInfo->GetDuration();
3128
3129 if(Player* modOwner = m_originalCaster->GetSpellModOwner())
3130 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3131
3132 Player* owner = m_originalCaster->ToPlayer();
3133 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3135
3136 if (!owner)
3137 {
3138 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3139 if (properties)
3140 {
3141 // Xinef: unsummon old guardian
3142 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3143 oldPet->UnSummon();
3144 SummonGuardian(effIndex, petentry, properties, 1, false);
3145 }
3146 return;
3147 }
3148
3149 Pet* OldSummon = owner->GetPet();
3150
3151 // if pet requested type already exist
3152 if (OldSummon)
3153 {
3154 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3155 {
3156 // pet in corpse state can't be summoned
3157 if (OldSummon->isDead())
3158 return;
3159
3160 ASSERT(OldSummon->GetMap() == owner->GetMap());
3161
3162 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3163
3164 float px, py, pz;
3165 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3166
3167 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3168 OldSummon->UpdateObjectVisibility();
3169
3170 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3171 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3172 // notify player
3173 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3174 owner->SendClearCooldown(itr->first, OldSummon);
3175
3176 // actually clear cooldowns
3177 OldSummon->m_CreatureSpellCooldowns.clear();
3178 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3179 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3180 {
3181 Aura const* aura = i->second->GetBase();
3182 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3183 OldSummon->RemoveAura(i);
3184 else
3185 ++i;
3186 }
3187 return;
3188 }
3189
3190 if (owner->IsPlayer())
3191 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3192 else
3193 return;
3194 }
3195
3196 float x, y, z;
3197 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3198 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3199 if (!pet)
3200 return;
3201
3202 if (m_caster->IsCreature())
3203 {
3204 if (m_caster->ToCreature()->IsTotem())
3206 else
3208 }
3209
3211
3212 // Reset cooldowns
3214 {
3215 pet->m_CreatureSpellCooldowns.clear();
3216 owner->PetSpellInitialize();
3217 }
3218
3219 // Set health to max if new pet is summoned
3220 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3221 // pet should have full health
3222 pet->SetHealth(pet->GetMaxHealth());
3223
3224 // generate new name for summon pet
3225 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3226 if (!new_name.empty())
3227 pet->SetName(new_name);
3228
3229 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3230}
@ SPELLMOD_DURATION
Definition: SpellDefines.h:78
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_AGGRESSIVE
Definition: Unit.h:550
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:252
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition: Creature.h:97
Definition: TemporarySummon.h:95
void SetName(std::string const &newname)
Definition: Object.h:459
float GetObjectSize() const
Definition: Object.cpp:2768
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14600
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:17264
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19058
Powers getPowerType() const
Definition: Unit.h:801
bool isDead() const
Definition: Unit.h:1153
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1137
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition: SpellEffects.cpp:5932

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4200{
4201 // workaround - this effect should not use target map
4203 return;
4204
4205 if (!unitTarget)
4206 return;
4207
4208 Player* player = unitTarget->ToPlayer();
4209 if (!player)
4210 {
4211 return;
4212 }
4213
4214 // Evil Twin (ignore player summon, but hide this for summoner)
4215 // Xinef: Unit Target may be on other map!!!, Need workaround
4216 if (unitTarget->HasAura(23445))
4217 return;
4218
4219 float x, y, z;
4220 m_caster->GetPosition(x, y, z);
4221
4222 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4223
4224 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4225 data << m_caster->GetGUID(); // summoner guid
4226 data << uint32(m_caster->GetZoneId()); // summoner zone
4227 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4228 player->GetSession()->SendPacket(&data);
4229}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:929
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16268

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6318{
6320 return;
6321
6322 if (!m_caster->IsPlayer())
6323 return;
6324
6325 if (!unitTarget)
6326 return;
6327
6328 Player* player = unitTarget->ToPlayer();
6329 if (!player)
6330 {
6331 return;
6332 }
6333
6334 float x, y, z;
6335 m_caster->GetPosition(x, y, z);
6337 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6338 data << m_caster->GetGUID();
6339 data << uint32(m_caster->GetZoneId());
6340 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6341 player->GetSession()->SendPacket(&data);
6342}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2312{
2314 return;
2315
2316 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2317 if (!entry)
2318 return;
2319
2320 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2321 if (!properties)
2322 {
2323 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2324 return;
2325 }
2326
2327 if (!m_originalCaster)
2328 return;
2329
2330 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2331 int32 duration = m_spellInfo->GetDuration();
2332 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2333 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2334
2335 TempSummon* summon = nullptr;
2336
2337 // determine how many units should be summoned
2338 uint32 numSummons;
2339
2340 // some spells need to summon many units, for those spells number of summons is stored in effect value
2341 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2342 // and in spell attributes, possibly we need to add a table for those)
2343 // so here's a list of MiscValueB values, which is currently most generic check
2344 switch (properties->Id)
2345 {
2346 case 64:
2347 case 61:
2348 case 1101:
2349 case 66:
2350 case 648:
2351 case 2301:
2352 case 1061:
2353 case 1261:
2354 case 629:
2355 case 181:
2356 case 715:
2357 case 1562:
2358 case 833:
2359 case 1161:
2360 case 713: // xinef, bloodworms
2361 numSummons = (damage > 0) ? damage : 1;
2362 break;
2363 default:
2364 numSummons = 1;
2365 break;
2366 }
2367
2368 switch (properties->Category)
2369 {
2373 if (properties->Flags & 512)
2374 {
2375 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2376 break;
2377 }
2378 switch (properties->Type)
2379 {
2380 case SUMMON_TYPE_PET:
2383 case SUMMON_TYPE_MINION:
2384 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2385 break;
2386 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2389 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2390 break;
2392 case SUMMON_TYPE_TOTEM:
2393 {
2394 // protection code
2395 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2396 if (!summon || !summon->IsTotem())
2397 return;
2398
2399 // Mana Tide Totem
2400 if (m_spellInfo->Id == 16190)
2402
2403 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2404 {
2405 summon->SetMaxHealth(damage);
2406 summon->SetHealth(damage);
2407 }
2408 break;
2409 }
2410 case SUMMON_TYPE_JEEVES:
2412 {
2413 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2414 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2415 return;
2416
2417 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2419
2420 summon->SetImmuneToAll(true);
2422
2423 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2424 //summon->AI()->EnterEvadeMode();
2425 if (properties->Type != SUMMON_TYPE_JEEVES)
2426 {
2427 summon->GetMotionMaster()->Clear(false);
2429 }
2430 break;
2431 }
2432 default:
2433 {
2434 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2435
2436 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2437
2438 for (uint32 count = 0; count < numSummons; ++count)
2439 {
2440 Position pos;
2441 if (count == 0)
2442 pos = *destTarget;
2443 else
2444 // randomize position for multiple summons
2445 pos = m_caster->GetRandomPoint(*destTarget, radius);
2446
2447 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2448 if (!summon)
2449 continue;
2450
2451 summon->SetTempSummonType(summonType);
2452
2453 if (properties->Category == SUMMON_CATEGORY_ALLY)
2454 {
2457 }
2458
2459 ExecuteLogEffectSummonObject(effIndex, summon);
2460 }
2461 return;
2462 }
2463 }//switch
2464 break;
2466 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2467 if (m_originalCaster)
2469 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2470 break;
2472 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2473 break;
2475 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2476 // to cast a ride vehicle spell on the summoned unit.
2477 //float x, y, z;
2478 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2479 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2480 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2482
2483 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2484 if (!summon || !summon->IsVehicle())
2485 return;
2486
2487 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2489 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2490 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2491 {
2492 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2493 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2494 spellId = spellInfo->Id;
2495 }
2496
2497 // xinef: if we have small value, it indicates seat position
2498 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2499 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2500 else
2501 m_originalCaster->CastSpell(summon, spellId, true);
2502
2503 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2504 //uint32 faction = properties->Faction;
2505 //if (!faction)
2506 uint32 faction = m_originalCaster->GetFaction();
2507
2508 summon->SetFaction(faction);
2509 break;
2510 }
2511
2512 if (summon)
2513 {
2515 ExecuteLogEffectSummonObject(effIndex, summon);
2516 }
2517}
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:52
TempSummonType
Definition: Object.h:44
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:51
@ REACT_PASSIVE
Definition: Unit.h:548
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:292
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2024
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3304
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3305
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3297
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3296
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3306
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3303
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3299
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3300
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3287
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3284
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3283
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3288
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1505
uint32 npcflag
Definition: CreatureData.h:202
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:277
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1502
void SetFaction(uint32 faction)
Definition: Unit.cpp:10001
virtual float GetFollowAngle() const
Definition: Unit.h:1735
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10518
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:748
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15466
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1160
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:994
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10803
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:1022
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition: Object.cpp:2163
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:409
void Clear(bool reset=true)
Definition: MotionMaster.h:165
uint32 Flags
Definition: DBCStructure.h:1915
uint32 Type
Definition: DBCStructure.h:1913
uint32 Id
Definition: DBCStructure.h:1910

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, MAX_VEHICLE_SEATS, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3063{
3065 return;
3066
3067 if (m_caster->GetPetGUID())
3068 return;
3069
3070 if (!unitTarget)
3071 return;
3072
3073 if (!unitTarget->IsCreature())
3074 return;
3075
3076 Creature* creatureTarget = unitTarget->ToCreature();
3077
3078 if (creatureTarget->IsPet())
3079 return;
3080
3082 return;
3083
3084 // cast finish successfully
3085 //SendChannelUpdate(0);
3086 finish();
3087
3088 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3089 if (!pet) // in very specific state like near world end/etc.
3090 return;
3091
3092 // "kill" original creature
3093 creatureTarget->DespawnOrUnsummon();
3094
3095 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3096
3097 // prepare visual effect for levelup
3098 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3099
3100 // add to world
3101 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3102
3103 // visual effect for levelup
3104 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3105
3106 // caster have pet now
3107 m_caster->SetMinion(pet, true);
3108
3109 pet->InitTalentForLevel();
3110
3111 if (m_caster->IsPlayer())
3112 {
3115 }
3116}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3259{
3261 return;
3262
3263 if (!unitTarget)
3264 return;
3265
3266 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3267 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3268 {
3269 m_caster->CastSpell(unitTarget, 67485, true);
3271 }
3272
3273 // this effect use before aura Taunt apply for prevent taunt already attacking target
3274 // for spell as marked "non effective at already attacking target"
3276 {
3278 return;
3279 }
3280
3282 {
3283 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3284 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3286 if (topThreat > myThreat)
3287 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3288
3289 //Set aggro victim to caster
3291 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3292 }
3293}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:49
float GetThreat() const
Definition: ThreatMgr.h:63
HostileReference * getMostHated() const
Definition: ThreatMgr.h:169
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:261
bool empty() const
Definition: ThreatMgr.h:164
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:276
bool CanHaveThreatList() const
Definition: Unit.cpp:14552

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1169{
1171 return;
1172
1173 if (!unitTarget || unitTarget->IsInFlight())
1174 return;
1175
1176 if (unitTarget->IsPlayer())
1177 {
1178 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1179 }
1180
1181 // Pre effects
1182 switch (m_spellInfo->Id)
1183 {
1184 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1185 if (Player* target = unitTarget->ToPlayer())
1186 {
1187 uint32 mapid = destTarget->GetMapId();
1188 float x, y, z, orientation;
1189 destTarget->GetPosition(x, y, z, orientation);
1190 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1191 }
1192 return;
1193 }
1194
1195 // If not exist data for dest location - return
1196 if (!m_targets.HasDst())
1197 {
1198 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1199 return;
1200 }
1201
1202 // Init dest coordinates
1203 uint32 mapid = destTarget->GetMapId();
1204 if (mapid == MAPID_INVALID)
1205 mapid = unitTarget->GetMapId();
1206 float x, y, z, orientation;
1207 destTarget->GetPosition(x, y, z, orientation);
1208 if (!orientation && m_targets.GetUnitTarget())
1209 orientation = m_targets.GetUnitTarget()->GetOrientation();
1210 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1211
1212 if (mapid == unitTarget->GetMapId())
1213 {
1214 if (unitTarget->GetVehicleKit()) // we are vehicle!
1215 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1216 else
1217 {
1219 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1220 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1222 }
1223 }
1224 else if (unitTarget->IsPlayer())
1225 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1226 else
1227 {
1228 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1229 return;
1230 }
1231
1232 // post effects for TARGET_DEST_DB
1233 switch (m_spellInfo->Id)
1234 {
1235 // Dimensional Ripper - Everlook
1236 case 23442:
1237 {
1238 int32 r = irand(0, 119);
1239 if (r >= 70) // 7/12 success
1240 {
1241 if (r < 100) // 4/12 evil twin
1242 m_caster->CastSpell(m_caster, 23445, true);
1243 else // 1/12 fire
1244 m_caster->CastSpell(m_caster, 23449, true);
1245 }
1246 return;
1247 }
1248 // Ultrasafe Transporter: Toshley's Station
1249 case 36941:
1250 {
1251 if (roll_chance_i(50)) // 50% success
1252 {
1253 int32 rand_eff = urand(1, 7);
1254 switch (rand_eff)
1255 {
1256 case 1:
1257 // soul split - evil
1258 m_caster->CastSpell(m_caster, 36900, true);
1259 break;
1260 case 2:
1261 // soul split - good
1262 m_caster->CastSpell(m_caster, 36901, true);
1263 break;
1264 case 3:
1265 // Increase the size
1266 m_caster->CastSpell(m_caster, 36895, true);
1267 break;
1268 case 4:
1269 // Decrease the size
1270 m_caster->CastSpell(m_caster, 36893, true);
1271 break;
1272 case 5:
1273 // Transform
1274 {
1276 m_caster->CastSpell(m_caster, 36897, true);
1277 else
1278 m_caster->CastSpell(m_caster, 36899, true);
1279 break;
1280 }
1281 case 6:
1282 // chicken
1283 m_caster->CastSpell(m_caster, 36940, true);
1284 break;
1285 case 7:
1286 // evil twin
1287 m_caster->CastSpell(m_caster, 23445, true);
1288 break;
1289 }
1290 }
1291 return;
1292 }
1293 }
1294}
#define MAPID_INVALID
Definition: Position.h:248
@ TELE_TO_SPELL
Definition: Player.h:825
@ TELE_TO_GM_MODE
Definition: Player.h:821
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2085
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1330
Vehicle * GetVehicleKit() const
Definition: Unit.h:1696
void TeleportVehicle(float x, float y, float z, float ang)
Definition: Vehicle.cpp:545

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3648{
3650 return;
3651
3652 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3653 return;
3654
3655 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3657 return;
3658
3660}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14591

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5866{
5868 return;
5869
5870 if (m_caster->IsPlayer())
5871 {
5872 if (Aura* aur = m_caster->GetAura(49152))
5873 aur->RecalculateAmountOfEffects();
5874 else
5875 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5876
5878 }
5879}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13091

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2800{
2802 return;
2803
2804 if (!m_caster->IsPlayer())
2805 return;
2806 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2807 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2808 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2809}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5340{
5342 return;
5343
5344 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5345
5346 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5347
5348 if (!goinfo)
5349 {
5350 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5351 return;
5352 }
5353
5354 float fx, fy, fz;
5355
5356 if (m_targets.HasDst())
5357 destTarget->GetPosition(fx, fy, fz);
5358 //FIXME: this can be better check for most objects but still hack
5359 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5360 {
5361 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5363 }
5364 else
5365 {
5366 //GO is always friendly to it's creator, get range for friends
5367 float min_dis = m_spellInfo->GetMinRange(true);
5368 float max_dis = m_spellInfo->GetMaxRange(true);
5369 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5370
5372 }
5373
5374 // Seaforium charge
5375 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5376 {
5377 fx = m_caster->GetPositionX();
5378 fy = m_caster->GetPositionY();
5379 fz = m_caster->GetPositionZ();
5380 }
5381
5382 Map* cMap = m_caster->GetMap();
5383
5384 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5385
5386 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5387 {
5388 delete pGameObj;
5389 return;
5390 }
5391
5392 int32 duration = m_spellInfo->GetDuration();
5393
5394 switch (goinfo->type)
5395 {
5397 {
5399 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5400
5401 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5402 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5403 int32 lastSec = 0;
5404 switch (urand(0, 2))
5405 {
5406 case 0:
5407 lastSec = 3;
5408 break;
5409 case 1:
5410 lastSec = 7;
5411 break;
5412 case 2:
5413 lastSec = 13;
5414 break;
5415 }
5416
5417 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5418 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5419
5420 break;
5421 }
5423 {
5424 if (m_caster->IsPlayer())
5425 {
5426 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5427 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5428 }
5429 break;
5430 }
5431 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5432 m_caster->AddGameObject(pGameObj);
5433 break;
5436 default:
5437 break;
5438 }
5439
5440 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5441
5442 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5443
5444 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5445 pGameObj->SetSpellId(m_spellInfo->Id);
5446
5447 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5448
5449 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5450 //m_caster->AddGameObject(pGameObj);
5451 //m_ObjToDel.push_back(pGameObj);
5452
5453 cMap->AddToMap(pGameObj, true);
5454
5455 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5456 {
5457 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5458 linkedTrap->SetSpellId(m_spellInfo->Id);
5459 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5460
5461 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5462 }
5463
5464 if (Player* player = m_caster->ToPlayer())
5465 {
5466 player->SetCanTeleport(true);
5467 }
5468}
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:118
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1576
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1578
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1577
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:164
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:927
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2313

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
947{
950 return;
951
952 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
953
954 // normal case
955 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
956 if (!spellInfo)
957 {
958 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
959 return;
960 }
961
962 SpellCastTargets targets;
964 {
965 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
966 return;
967 targets.SetUnitTarget(unitTarget);
968 }
969 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
970 {
971 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
972 return;
973
975 targets.SetDst(m_targets);
976
977 targets.SetUnitTarget(m_caster);
978 }
979
980 CustomSpellValues values;
981 // set basepoints for trigger with value effect
983 {
984 // maybe need to set value only when basepoints == 0?
988 }
989
990 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
991 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
992 {
993 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
994 }
995
996 // original caster guid only for GO cast
997 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
998}
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:926
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1037
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1055{
1057 return;
1058
1059 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1060 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1061
1062 if (!spellInfo)
1063 {
1064 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1065 return;
1066 }
1067
1068 finish();
1069
1070 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1071}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
790{
793 return;
794
795 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
796
798 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
800 {
801 // special cases
802 switch (triggered_spell_id)
803 {
804 // Mirror Image
805 case 58832:
806 {
807 // Glyph of Mirror Image
808 if (m_caster->HasAura(63093))
809 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
810
811 break;
812 }
813 // Demonic Empowerment -- succubus
814 case 54437:
815 {
819
820 // Cast Lesser Invisibility
821 unitTarget->CastSpell(unitTarget, 7870, true);
822 return;
823 }
824 // just skip
825 case 23770: // Sayge's Dark Fortune of *
826 // not exist, common cooldown can be implemented in scripts if need.
827 return;
828 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
829 case 29284:
830 {
831 // Brittle Armor
832 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
833 if (!spell)
834 return;
835
836 for (uint32 j = 0; j < spell->StackAmount; ++j)
837 m_caster->CastSpell(unitTarget, spell->Id, true);
838 return;
839 }
840 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
841 case 29286:
842 {
843 // Mercurial Shield
844 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
845 if (!spell)
846 return;
847
848 for (uint32 j = 0; j < spell->StackAmount; ++j)
849 m_caster->CastSpell(unitTarget, spell->Id, true);
850 return;
851 }
852 // Cloak of Shadows
853 case 35729:
854 {
857 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
858 {
859 // remove all harmful spells on you...
860 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
861
862 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
863 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
864 return;
865
866 bool dmgClassNone = false;
868 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
869 {
870 if ((iter->second->GetEffectMask() & (1 << i)) &&
871 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
872 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
873 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
874 {
875 dmgClassNone = false;
876 break;
877 }
878 dmgClassNone = true;
879 }
880
881 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
882 // ignore positive and passive auras
883 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
884 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
886 {
887 m_caster->RemoveAura(iter);
888 }
889 else
890 ++iter;
891 }
892 return;
893 }
894 }
895 }
896
897 // normal case
898 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
899 if (!spellInfo)
900 {
901 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
902 return;
903 }
904
905 SpellCastTargets targets;
907 {
908 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
909 return;
910 targets.SetUnitTarget(unitTarget);
911 }
912 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
913 {
914 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
915 return;
916
918 targets.SetDst(m_targets);
919
920 if (Unit* target = m_targets.GetUnitTarget())
921 targets.SetUnitTarget(target);
922 else
923 targets.SetUnitTarget(m_caster);
924 }
925
926 CustomSpellValues values;
927 // set basepoints for trigger with value effect
929 {
930 // maybe need to set value only when basepoints == 0?
934 }
935
936 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
937 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
938 {
939 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
940 }
941
942 // original caster guid only for GO cast
944}
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:842
@ MECHANIC_BLEED
Definition: SharedDefines.h:1340
@ DISPEL_ALL
Definition: SharedDefines.h:1379

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1319{
1321 return;
1322
1323 if (!unitTarget)
1324 return;
1325
1326 Player* player = unitTarget->ToPlayer();
1327 if (!player)
1328 {
1329 return;
1330 }
1331
1332 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1333
1334 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1335 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1336 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1337}
#define SPEC_MASK_ALL
Definition: Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3312

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2724{
2726 return;
2727
2728 if (!unitTarget || m_caster->IsPlayer())
2729 return;
2730
2731 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2733}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8835

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
248{
249 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
250}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3296{
3298 return;
3299
3300 if (!unitTarget || !unitTarget->IsAlive())
3301 return;
3302
3303 // multiple weapon dmg effect workaround
3304 // execute only the last weapon damage
3305 // and handle all effects at once
3306 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3307 {
3308 switch (m_spellInfo->Effects[j].Effect)
3309 {
3314 return; // we must calculate only at last weapon effect
3315 break;
3316 }
3317 }
3318
3319 // some spell specific modifiers
3320 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3321 int32 spell_bonus = 0; // bonus specific for spell
3322 bool normalized = false;
3323
3325 {
3327 {
3328 switch (m_spellInfo->Id)
3329 {
3330 // Trial of the Champion, Black Knight, Obliterate
3331 case 67725:
3332 case 67883:
3333 {
3334 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3335 break;
3336 }
3337 }
3338 break;
3339 }
3341 {
3342 // Devastate (player ones)
3343 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3344 {
3345 m_caster->CastSpell(unitTarget, 58567, true);
3346
3347 if (Aura* aur = unitTarget->GetAura(58567))
3348 {
3349 // 58388 - Glyph of Devastate dummy aura.
3350 if (m_caster->HasAura(58388))
3351 aur->ModStackAmount(1);
3352
3353 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3354 }
3355 }
3356 break;
3357 }
3358 case SPELLFAMILY_ROGUE:
3359 {
3360 // Fan of Knives, Hemorrhage, Ghostly Strike
3361 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3362 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3363 {
3364 // Hemorrhage
3365 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3366 {
3368 }
3369 // 50% more damage with daggers
3370 if (m_caster->IsPlayer())
3371 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3372 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3373 AddPct(totalDamagePercentMod, 50.0f);
3374 }
3375 // Mutilate (for each hand)
3376 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3377 {
3378 bool found = false;
3379 // fast check
3381 found = true;
3382 // full aura scan
3383 else
3384 {
3386 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3387 {
3388 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3389 {
3390 found = true;
3391 break;
3392 }
3393 }
3394 }
3395
3396 if (found)
3397 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3398 }
3399 break;
3400 }
3402 {
3403 switch (m_spellInfo->Id)
3404 {
3405 case 20467: // Seal of Command Unleashed
3406 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3408 break;
3409 case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
3410 case 53739:
3412 AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
3413 break;
3414 case 53385: // Divine Storm deals normalized damage
3415 normalized = true;
3416 break;
3417 default:
3418 break;
3419 }
3420 break;
3421 }
3422 case SPELLFAMILY_SHAMAN:
3423 {
3424 // Skyshatter Harness item set bonus
3425 // Stormstrike
3426 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3427 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3428 // Lava lash damage increased by Flametongue weapon
3430 AddPct(totalDamagePercentMod, 25.0f);
3431 break;
3432 }
3433 case SPELLFAMILY_DRUID:
3434 {
3435 // Mangle (Cat): CP
3436 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3437 {
3439 }
3440 // Shred, Maul - Rend and Tear
3442 {
3443 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3444 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3445 }
3446 break;
3447 }
3448 case SPELLFAMILY_HUNTER:
3449 {
3450 // Kill Shot
3451 if( m_spellInfo->SpellFamilyFlags[1] & 0x800000 )
3452 {
3453 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3454 }
3455 break;
3456 }
3458 {
3459 // Plague Strike
3460 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3461 {
3462 // Glyph of Plague Strike
3463 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3464 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3465 break;
3466 }
3467 // Blood Strike
3468 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3469 {
3470 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3471 //Death Knight T8 Melee 4P Bonus
3472 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3473 AddPct(disease_amt, aurEff->GetAmount());
3474
3475 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3476
3477 // Glyph of Blood Strike
3478 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3480 AddPct(totalDamagePercentMod, 20.0f);
3481 break;
3482 }
3483 // Death Strike
3484 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3485 {
3486 // Glyph of Death Strike
3487 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3488 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3489 AddPct(totalDamagePercentMod, runic);
3490 break;
3491 }
3492 // Obliterate (12.5% more damage per disease)
3493 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3494 {
3495 bool consumeDiseases = true;
3496 // Annihilation
3498 // Do not consume diseases if roll sucesses
3499 if (roll_chance_i(aurEff->GetAmount()))
3500 consumeDiseases = false;
3501
3502 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3503 //Death Knight T8 Melee 4P Bonus
3504 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3505 AddPct(disease_amt, aurEff->GetAmount());
3506
3507 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3508 break;
3509 }
3510 // Blood-Caked Strike - Blood-Caked Blade
3511 if (m_spellInfo->SpellIconID == 1736)
3512 {
3513 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
3514 ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
3515 spell_bonus = weaponDamage;
3516 break;
3517 }
3518 // Heart Strike
3519 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3520 {
3521 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3522 //Death Knight T8 Melee 4P Bonus
3523 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3524 AddPct(disease_amt, aurEff->GetAmount());
3525
3526 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3527 break;
3528 }
3529 // Rune Strike
3530 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3531 {
3532 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3533 }
3534
3535 break;
3536 }
3537 }
3538
3539 float weaponDamagePercentMod = 100.0f;
3540 int32 fixed_bonus = 0;
3541
3542 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3543 {
3544 switch (m_spellInfo->Effects[j].Effect)
3545 {
3548 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3549 break;
3551 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3552 normalized = true;
3553 break;
3555 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3556 break;
3557 default:
3558 break; // not weapon damage effect, just skip
3559 }
3560 }
3561
3562 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
3563 if (fixed_bonus || spell_bonus)
3564 {
3565 UnitMods unitMod;
3566 switch (m_attackType)
3567 {
3568 default:
3569 case BASE_ATTACK:
3570 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3571 break;
3572 case OFF_ATTACK:
3573 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3574 break;
3575 case RANGED_ATTACK:
3576 unitMod = UNIT_MOD_DAMAGE_RANGED;
3577 break;
3578 }
3579
3581 {
3582 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3583 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3584 spell_bonus = int32(spell_bonus * weapon_total_pct);
3585 }
3586 }
3587
3588 int32 weaponDamage = 0;
3589 // Dancing Rune Weapon
3590 if (m_caster->GetEntry() == 27893)
3591 {
3592 if (Unit* owner = m_caster->GetOwner())
3593 weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
3594 }
3595 else if (m_spellInfo->Id == 5019) // Wands
3596 {
3597 weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
3598 }
3599 else
3600 {
3601 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
3602 }
3603
3604 // Sequence is important
3605 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3606 {
3607 // We assume that a spell have at most one fixed_bonus
3608 // and at most one weaponDamagePercentMod
3609 switch (m_spellInfo->Effects[j].Effect)
3610 {
3614 weaponDamage += fixed_bonus;
3615 break;
3617 ApplyPct(weaponDamage, weaponDamagePercentMod);
3618 default:
3619 break; // not weapon damage effect, just skip
3620 }
3621 }
3622
3623 weaponDamage += spell_bonus;
3624 ApplyPct(weaponDamage, totalDamagePercentMod);
3625
3626 // prevent negative damage
3627 uint32 eff_damage(std::max(weaponDamage, 0));
3628
3629 // Add melee damage bonuses (also check for negative)
3632
3633 // Meteor like spells (divided damage to targets)
3635 {
3636 uint32 count = 0;
3637 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3638 if (ihit->effectMask & (1 << effIndex))
3639 ++count;
3640
3641 eff_damage /= count; // divide to all targets
3642 }
3643
3644 m_damage += eff_damage;
3645}
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:359
UnitMods
Definition: Unit.h:142
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:166
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:167
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:165
@ TOTAL_PCT
Definition: Unit.h:129
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:275
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:899
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:809
@ AURA_STATE_DEADLY_POISON
Definition: SharedDefines.h:1308
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1310
@ DISPEL_POISON
Definition: SharedDefines.h:1376
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13216
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:5775
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:5504
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition: Unit.cpp:15226
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:2951
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:11877
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13014

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5136{
5137 InitEffectExecuteData(effIndex);
5138 *m_effectExecuteData[effIndex] << uint32(entry);
5139}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8464

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5142{
5143 InitEffectExecuteData(effIndex);
5144 *m_effectExecuteData[effIndex] << uint32(entry);
5145}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5122{
5123 InitEffectExecuteData(effIndex);
5124 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5125 *m_effectExecuteData[effIndex] << int32(itemId);
5126 *m_effectExecuteData[effIndex] << int32(slot);
5127}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5108{
5109 InitEffectExecuteData(effIndex);
5110 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5111 *m_effectExecuteData[effIndex] << uint32(attCount);
5112}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5115{
5116 InitEffectExecuteData(effIndex);
5117 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5118 *m_effectExecuteData[effIndex] << uint32(spellId);
5119}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5130{
5131 InitEffectExecuteData(effIndex);
5132 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5133}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5160{
5161 InitEffectExecuteData(effIndex);
5162 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5163}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5099{
5100 InitEffectExecuteData(effIndex);
5101 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5102 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5103 *m_effectExecuteData[effIndex] << uint32(PowerType);
5104 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5105}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5154{
5155 InitEffectExecuteData(effIndex);
5156 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5157}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4474{
4475 if (!m_caster)
4476 return;
4477
4479 return;
4481
4482 if (m_spellInfo->IsChanneled())
4484
4487
4488 // Unsummon summon as possessed creatures on spell cancel
4490 {
4491 if (Unit* charm = m_caster->GetCharm())
4492 if (charm->IsCreature()
4493 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4494 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4495 ((Puppet*)charm)->UnSummon();
4496 }
4497
4498 if (Creature* creatureCaster = m_caster->ToCreature())
4499 creatureCaster->ReleaseFocus(this);
4500
4501 if (ok)
4502 {
4505 }
4506 else
4507 {
4508 if (m_caster->IsPlayer())
4509 {
4510 // Xinef: Restore spell mods in case of fail cast
4512
4513 // Xinef: Reset cooldown event in case of fail cast
4516 }
4517 return;
4518 }
4519
4520 // pussywizard:
4523
4525 {
4526 // Unsummon statue
4528 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4529 if (spellInfo && spellInfo->SpellIconID == 2056)
4530 {
4531 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4532 m_caster->setDeathState(DeathState::JustDied);
4533 return;
4534 }
4535 }
4536
4537 // potions disabled by client, send event "not in combat" if need
4540
4541 // Take mods after trigger spell (needed for 14177 to affect 48664)
4542 // mods are taken only on succesfull cast and independantly from targets of the spell
4543 if (Player* player = m_caster->GetSpellModOwner())
4544 player->RemoveSpellMods(this);
4545
4546 // xinef: clear reactive auras states after spell cast
4549
4550 // Stop Attack for some spells
4553}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:309
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:207
@ UNIT_MASK_PUPPET
Definition: UnitDefines.h:141
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1292
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1298
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1497
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14490
void UpdateInterruptMask()
Definition: Unit.cpp:741
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10442
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3471

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8460{
8462}
void SendLogExecute()
Definition: Spell.cpp:5064

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline
547{ return m_casttime; }

References m_casttime.

Referenced by Unit::InterruptSpell(), and Unit::SetCurrentCastedSpell().

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8923{
8924 std::stringstream sstr;
8925 sstr << std::boolalpha
8926 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8927 << " State: " << getState();
8928 return sstr.str();
8929}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
562{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
565{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
576{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2111{
2112 // this function selects which containers need to be searched for spell target
2114
2115 // filter searchers based on searched object type
2116 switch (objType)
2117 {
2124 break;
2128 break;
2129 default:
2130 break;
2131 }
2133 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2137 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2138
2139 if (condList)
2140 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2141 return retMask;
2142}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:70
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:74
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:69
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:104
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:505
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
583{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
591{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4167{
4168 if (!UpdatePointers())
4169 {
4170 // finish the spell if UpdatePointers() returned false, something wrong happened there
4171 finish(false);
4172 return 0;
4173 }
4174
4175 Player* modOwner = m_caster->GetSpellModOwner();
4176 if (modOwner)
4177 modOwner->SetSpellModTakingSpell(this, true);
4178
4179 uint64 next_time = m_delayTrajectory;
4180
4182
4183 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4184 {
4186 m_immediateHandled = true;
4188 next_time = 0;
4189 }
4190
4191 bool single_missile = (m_targets.HasDst());
4192
4193 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4194 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4195 {
4196 if (ihit->processed == false)
4197 {
4198 if (single_missile || ihit->timeDelay <= t_offset)
4199 {
4200 ihit->timeDelay = t_offset;
4201 DoAllEffectOnTarget(&(*ihit));
4202 }
4203 else if (next_time == 0 || ihit->timeDelay < next_time)
4204 next_time = ihit->timeDelay;
4205 }
4206 }
4207
4208 // now recheck gameobject targeting correctness
4209 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4210 {
4211 if (ighit->processed == false)
4212 {
4213 if (single_missile || ighit->timeDelay <= t_offset)
4214 DoAllEffectOnTarget(&(*ighit));
4215 else if (next_time == 0 || ighit->timeDelay < next_time)
4216 next_time = ighit->timeDelay;
4217 }
4218 }
4219
4221
4222 if (modOwner)
4223 modOwner->SetSpellModTakingSpell(this, false);
4224
4225 // All targets passed - need finish phase
4226 if (next_time == 0)
4227 {
4228 // spell is finished, perform some last features of the spell here
4230
4231 finish(true); // successfully finish spell cast
4232
4233 // return zero, spell is finished now
4234 return 0;
4235 }
4236 else
4237 {
4238 // spell is unfinished, return next execution time
4239 return next_time;
4240 }
4241}
void _handle_finish_phase()
Definition: Spell.cpp:4271
void PrepareTargetProcessing()
Definition: Spell.cpp:8454
void _handle_immediate_phase()
Definition: Spell.cpp:4243
void FinishTargetProcessing()
Definition: Spell.cpp:8459

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4107{
4108 // start channeling if applicable
4109 if (m_spellInfo->IsChanneled())
4110 {
4111 int32 duration = m_spellInfo->GetDuration();
4113 duration = -1;
4114
4115 if (duration > 0)
4116 {
4117 // First mod_duration then haste - see Missile Barrage
4118 // Apply duration mod
4119 if (Player* modOwner = m_caster->GetSpellModOwner())
4120 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4121
4122 // Apply haste mods
4124 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4125
4128 m_channeledDuration = duration;
4129 SendChannelStart(duration);
4130 }
4131 else if (duration == -1)
4132 {
4135 SendChannelStart(duration);
4136 }
4137 }
4138
4140
4141 // process immediate effects (items, ground, etc.) also initialize some variables
4143
4144 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4145 DoAllEffectOnTarget(&(*ihit));
4146
4147 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4148 DoAllEffectOnTarget(&(*ihit));
4149
4151
4152 // spell is finished, perform some last features of the spell here
4154
4155 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4156 TakeCastItem();
4157
4158 // handle ammo consumption for Hunter's volley spell
4160 TakeAmmo();
4161
4163 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4164}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:1506
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5197
void TakeAmmo()
Definition: Spell.cpp:5370

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5619{
5621 return;
5622
5623 effectHandleMode = mode;
5624 unitTarget = pUnitTarget;
5625 itemTarget = pItemTarget;
5626 gameObjTarget = pGOTarget;
5628
5629 uint8 eff = m_spellInfo->Effects[i].Effect;
5630
5631 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5632
5633 // we do not need DamageMultiplier here.
5634 damage = CalculateSpellDamage(i, nullptr);
5635
5636 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5637
5638 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5639 {
5640 (this->*SpellEffects[eff])((SpellEffIndex)i);
5641 }
5642}
SpellEffIndex
Definition: SharedDefines.h:30
SpellEffects
Definition: SharedDefines.h:778
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
WorldLocation _position
Definition: Spell.h:103
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8573

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8223{
8224 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8225 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8226 {
8227 // don't do anything for empty effect
8228 if (!m_spellInfo->Effects[i].IsEffect())
8229 continue;
8230
8231 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8232 }
8233
8234 float multiplier[MAX_SPELL_EFFECTS];
8235 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8236 if (m_applyMultiplierMask & (1 << i))
8237 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8238
8241 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8242 {
8243 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8244 usesAmmo = false;
8245 }
8246
8248
8249 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8250 {
8251 TargetInfo& target = *ihit;
8252
8253 uint32 mask = target.effectMask;
8254 if (!mask)
8255 continue;
8256
8257 // do not consume ammo anymore for Hunter's volley spell
8259 usesAmmo = false;
8260
8261 if (usesAmmo)
8262 {
8263 bool ammoTaken = false;
8264 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8265 {
8266 if (!(mask & 1 << i))
8267 continue;
8268 switch (m_spellInfo->Effects[i].Effect)
8269 {
8275 ammoTaken = true;
8276 TakeAmmo();
8277 }
8278 if (ammoTaken)
8279 break;
8280 }
8281 }
8282
8283 DoAllEffectOnLaunchTarget(target, multiplier);
8284 }
8285
8287}
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition: SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:780
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8289

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5572{
5573 if (m_UniqueTargetInfo.empty())
5574 return;
5575
5577 return;
5578
5579 float threat = 0.0f;
5580 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5581 {
5582 if (threatEntry->apPctMod != 0.0f)
5583 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5584
5585 threat += threatEntry->flatMod;
5586 }
5588 threat += m_spellInfo->SpellLevel;
5589
5590 // past this point only multiplicative effects occur
5591 if (threat == 0.0f)
5592 return;
5593
5594 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5595 threat /= m_UniqueTargetInfo.size();
5596
5597 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5598 {
5599 float threatToAdd = threat;
5600 if (ihit->missCondition != SPELL_MISS_NONE)
5601 threatToAdd = 0.0f;
5602
5603 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5604 if (!target)
5605 continue;
5606
5607 bool IsFriendly = m_caster->IsFriendlyTo(target);
5608 // positive spells distribute threat among all units that are in combat with target, like healing
5610 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5611 // for negative spells threat gets distributed among affected targets
5612 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5613 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5614 }
5615 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5616}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:178
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2839
Definition: SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8093{
8094 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8095 if (itr->effectMask & (1 << effect))
8096 return true;
8097
8098 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8099 if (itr->effectMask & (1 << effect))
8100 return true;
8101
8102 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8103 if (itr->effectMask & (1 << effect))
8104 return true;
8105
8106 return false;
8107}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8465{
8466 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8467 if (!m_effectExecuteData[effIndex])
8468 {
8469 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8470 // first dword - target counter
8471 *m_effectExecuteData[effIndex] << uint32(1);
8472 }
8473 else
8474 {
8475 // increase target counter by one
8476 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8477 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8478 }
8479}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
715{
716 m_targets = targets;
717 // this function tries to correct spell explicit targets for spell
718 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
719 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
720 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
721
722 if (WorldObject* target = m_targets.GetObjectTarget())
723 {
724 // check if object target is valid with needed target flags
725 // for unit case allow corpse target mask because player with not released corpse is a unit target
726 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
727 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
728 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
730 }
731 else
732 {
733 // try to select correct unit target if not provided by client or by serverside cast
734 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
735 {
736 Unit* unit = nullptr;
737 // try to use player selection as a target
738 if (Player* playerCaster = m_caster->ToPlayer())
739 {
740 // selection has to be found and to be valid target for the spell
741 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
743 unit = selectedUnit;
744 }
745 // try to use attacked unit as a target
746 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
747 unit = m_caster->GetVictim();
748
749 // didn't find anything - let's use self as target
750 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
751 unit = m_caster;
752
754 }
755 }
756
757 // check if spell needs dst target
758 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
759 {
760 // and target isn't set
761 if (!m_targets.HasDst())
762 {
763 // try to use unit target if provided
764 if (WorldObject* target = targets.GetObjectTarget())
765 m_targets.SetDst(*target);
766 // or use self if not available
767 else
769 }
770 }
771 else
773
774 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
775 {
776 if (!targets.HasSrc())
778 }
779 else
781}
@ TARGET_FLAG_UNIT_RAID
Definition: SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellInfo.h:49
void RemoveObjectTarget()
Definition: Spell.cpp:322
void RemoveDst()
Definition: Spell.cpp:449
void RemoveSrc()
Definition: Spell.cpp:392

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8067{
8070 {
8071 return false;
8072 }
8073
8075 {
8076 return false;
8077 }
8078
8079 return true;
8080}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:629

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
629 {
630 if (m_delayAtDamageCount >= 2)
631 return true;
632
634 return false;
635 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
560{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8215{
8216 if (target->IsAlive())
8218
8220}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1221
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1226

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8488{
8489 if (_scriptsLoaded)
8490 return;
8491 _scriptsLoaded = true;
8492 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8493 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8494 {
8495 if (!(*itr)->_Load(this))
8496 {
8497 std::list<SpellScript*>::iterator bitr = itr;
8498 ++itr;
8499 delete (*bitr);
8500 m_loadedScripts.erase(bitr);
8501 continue;
8502 }
8503 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8504 (*itr)->Register();
8505 ++itr;
8506 }
8507}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8893{
8894 if (!m_caster || !m_caster->IsInWorld())
8895 return;
8896
8897 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8898
8899 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8900 // can succeed with a lockId of 0
8901 if (m_spellInfo->Id == 21651)
8902 {
8903 if (GameObject* go = m_targets.GetGOTarget())
8904 {
8905 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8906 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8907 {
8908 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8909 visual->prepare(&m_targets);
8910 }
8911 }
8912 }
8913}
@ TRIGGERED_NONE
Definition: SpellDefines.h:131
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2608

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3469{
3470 if (m_CastItem)
3471 {
3473 }
3474 else
3475 {
3477 }
3478
3479 InitExplicitTargets(*targets);
3480
3481 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3482 {
3483 finish(false);
3484 return SPELL_FAILED_UNKNOWN;
3485 }
3486
3487 // Fill aura scaling information
3489 {
3490 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3491 {
3492 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3495 {
3496 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3498 {
3499 m_auraScaleMask |= (1 << i);
3500 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3501 {
3502 m_auraScaleMask = 0;
3503 break;
3504 }
3505 }
3506 }
3507 }
3508 }
3509
3511
3512 if (triggeredByAura)
3513 {
3514 m_triggeredByAuraSpell.Init(triggeredByAura);
3515 }
3516
3517 // create and add update event for this spell
3518 _spellEvent = new SpellEvent(this);
3520
3522 {
3524 finish(false);
3526 }
3527
3528 //Prevent casting at cast another spell (ServerSide check)
3530 {
3532 finish(false);
3534 }
3535
3536 LoadScripts();
3537
3538 OnSpellLaunch();
3539
3541
3542 // Set combo point requirement
3544 m_needComboPoints = false;
3545
3546 SpellCastResult result = CheckCast(true);
3547 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3548 {
3549 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3550 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3551 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3552 // a possible alternative sollution for those would be validating aura target on unit state change
3553 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3554 {
3556 triggeredByAura->GetBase()->SetDuration(0);
3557 }
3558
3559 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3561 {
3562 SendCastResult(result);
3563
3564 finish(false);
3565 return result;
3566 }
3567 }
3568
3569 // Prepare data for triggers
3570 prepareDataForTriggerSystem(triggeredByAura);
3571
3572 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3574
3575 if (m_caster->IsPlayer())
3577 m_casttime = 0;
3578
3579 // don't allow channeled spells / spells with cast time to be casted while moving
3580 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3582 {
3583 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3585 {
3587 finish(false);
3588 return SPELL_FAILED_MOVING;
3589 }
3590 }
3591
3592 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3593 if (m_CastItem)
3594 {
3595 bool selectTargets = false;
3596 bool nearbyDest = false;
3597
3598 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3599 {
3600 if (!m_spellInfo->Effects[i].IsEffect())
3601 continue;
3602
3603 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3604 {
3605 selectTargets = false;
3606 break;
3607 }
3608
3609 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3610 {
3611 nearbyDest = true;
3612 }
3613
3614 // xinef: by default set it to false, and to true if any valid target is found
3615 selectTargets = true;
3616 }
3617
3618 if (selectTargets)
3619 {
3621 _spellTargetsSelected = true;
3622 bool spellFailed = false;
3623
3624 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3625 {
3626 // no valid nearby target unit or game object found; check if nearby destination type
3627 if (nearbyDest)
3628 {
3629 if (!m_targets.HasDst())
3630 {
3631 // no valid target destination
3632 spellFailed = true;
3633 }
3634 }
3635 else
3636 {
3637 spellFailed = true;
3638 }
3639 }
3640
3641 if (spellFailed)
3642 {
3644 finish(false);
3646 }
3647 }
3648 }
3649
3650 // set timer base at cast time
3651 ReSetTimer();
3652
3653 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3654
3656 {
3658 }
3659
3660 //Containers for channeled spells have to be set
3661 //TODO:Apply this to all casted spells if needed
3662 // Why check duration? 29350: channelled triggers channelled
3664 cast(true);
3665 else
3666 {
3667 // stealth must be removed at cast starting (at show channel bar)
3668 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3670 {
3671 // Farsight spells exception
3672 uint32 exceptSpellId = 0;
3674 {
3675 exceptSpellId = m_spellInfo->Id;
3676 }
3677
3680 }
3681
3684
3685 // set target for proper facing
3687 {
3690 {
3691 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3692 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3694 }
3695 }
3696
3697 //item: first cast may destroy item and second cast causes crash
3698 // xinef: removed !m_spellInfo->StartRecoveryTime
3699 // second los check failed in events
3700 // xinef: removed itemguid check, currently there is no such item in database
3702 cast(true);
3703
3706 }
3707
3708 return SPELL_CAST_OK;
3709}
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:57
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:46
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:136
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:140
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:138
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:27
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ CHEAT_CASTTIME
Definition: Player.h:1000
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:813
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3538
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3924
bool IsSitState() const
Definition: Unit.cpp:16650
Definition: Spell.cpp:520
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8915
void LoadScripts()
Definition: Spell.cpp:8487
void cast(bool skipCheck=false)
Definition: Spell.cpp:3782
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2292
void SendSpellStart()
Definition: Spell.cpp:4708
void TriggerGlobalCooldown()
Definition: Spell.cpp:8831
void OnSpellLaunch()
Definition: Spell.cpp:8892
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7902
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:714
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1260
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2344
uint32 Attributes
Definition: SpellInfo.h:324
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1270

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, Unit::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2293{
2294 //==========================================================================================
2295 // Now fill data for trigger system, need know:
2296 // can spell trigger another or not (m_canTrigger)
2297 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2298 //==========================================================================================
2299
2301 // Get data for type of attack and fill base info for trigger
2302 switch (m_spellInfo->DmgClass)
2303 {
2306 if (m_attackType == OFF_ATTACK)
2308 else
2311 break;
2313 // Auto attack
2315 {
2318 }
2319 else // Ranged spell attack
2320 {
2323 }
2324 break;
2325 default:
2328 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2329 {
2332 }
2333 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2334 // Because spell positivity is dependant on target
2335 }
2337
2338 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2340 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2341 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2342 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2343 {
2345 }
2346
2347 /* Effects which are result of aura proc from triggered spell cannot proc
2348 to prevent chain proc of these spells */
2349
2350 // Hellfire Effect - trigger as DOT
2352 {
2355 }
2356
2357 // Ranged autorepeat attack is set as triggered spell - ignore it
2359 {
2366 }
2367 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2370}
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:146
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:486
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:502

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8568{
8569 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8570 (*scritr)->_InitHit();
8571}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8742{
8745 {
8746 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8747 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8749 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8750 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8752 }
8753
8756 {
8758 {
8759 if( m_spellInfo->SpellFamilyFlags[1] & 0x40000000 )
8760 {
8762 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8763 {
8764 if( (*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8765 {
8766 m_preCastSpell = 26017;
8767 break;
8768 }
8769 else if( (*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8770 m_preCastSpell = 67;
8771 }
8772 }
8773 break;
8774 }
8775 case SPELLFAMILY_DRUID:
8776 {
8777 // Faerie Fire (Feral)
8779 m_preCastSpell = 60089;
8780
8781 break;
8782 }
8783 }
8784
8785 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8786 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8787 // and to correctly calculate proc chance when combopoints are present
8789 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8790 {
8791 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8792 continue;
8793 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8794 uint32 auraSpellIdx = (*i)->GetEffIndex();
8795 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8796 {
8797 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8798 // this possibly needs fixing
8799 int32 auraBaseAmount = (*i)->GetBaseAmount();
8800 // proc chance is stored in effect amount
8801 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8802 // build trigger and add to the list
8803 HitTriggerSpell spellTriggerInfo;
8804 spellTriggerInfo.triggeredSpell = spellInfo;
8805 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8806 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8807 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8808 m_hitTriggerSpells.push_back(spellTriggerInfo);
8809 }
8810 }
8811}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
@ FORM_DIREBEAR
Definition: UnitDefines.h:77
@ FORM_BEAR
Definition: UnitDefines.h:74
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
918{
921}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:896
uint64 GetDelayStart() const
Definition: Spell.h:562

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, Unit::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
550{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2187{
2188 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2189 if (!containerTypeMask)
2190 return;
2191 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2192 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2193 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2194}
Definition: GridNotifiers.h:239
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2110

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2197{
2198 // max dist for jump target selection
2199 float jumpRadius = 0.0f;
2200 switch (m_spellInfo->DmgClass)
2201 {
2203 // 7.5y for multi shot
2204 jumpRadius = 7.5f;
2205 break;
2207 // 5y for swipe, cleave and similar
2208 jumpRadius = 5.0f;
2209 break;
2212 // 12.5y for chain heal spell since 3.2 patch
2213 if (isChainHeal)
2214 jumpRadius = 12.5f;
2215 // 10y as default for magic chain spells
2216 else
2217 jumpRadius = 10.0f;
2218 break;
2219 }
2220
2221 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2225
2226 // max dist which spell can reach
2227 float searchRadius = jumpRadius;
2228 if (isBouncingFar)
2229 searchRadius *= chainTargets;
2230
2231 std::list<WorldObject*> tempTargets;
2232 SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
2233 tempTargets.remove(target);
2234
2235 // remove targets which are always invalid for chain spells
2236 // for some spells allow only chain targets in front of caster (swipe for example)
2237 if (!isBouncingFar)
2238 {
2239 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
2240 {
2241 std::list<WorldObject*>::iterator checkItr = itr++;
2242 if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
2243 tempTargets.erase(checkItr);
2244 }
2245 }
2246
2247 while (chainTargets)
2248 {
2249 // try to get unit for next chain jump
2250 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2251 // get unit with highest hp deficit in dist
2252 if (isChainHeal)
2253 {
2254 uint32 maxHPDeficit = 0;
2255 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2256 {
2257 if (Unit* unit = (*itr)->ToUnit())
2258 {
2259 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2260 if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2261 {
2262 foundItr = itr;
2263 maxHPDeficit = deficit;
2264 }
2265 }
2266 }
2267 }
2268 // get closest object
2269 else
2270 {
2271 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2272 {
2273 if (foundItr == tempTargets.end())
2274 {
2275 if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2276 foundItr = itr;
2277 }
2278 else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2279 foundItr = itr;
2280 }
2281 }
2282 // not found any valid target - chain ends
2283 if (foundItr == tempTargets.end())
2284 break;
2285 target = *foundItr;
2286 tempTargets.erase(foundItr);
2287 targets.push_back(target);
2288 --chainTargets;
2289 }
2290}
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition: SharedDefines.h:548
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1316
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1381
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition: Spell.cpp:2186

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2175{
2176 WorldObject* target = nullptr;
2177 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2178 if (!containerTypeMask)
2179 return nullptr;
2180 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2182 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2183 return target;
2184}
Definition: GridNotifiers.h:219

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2146{
2147 if (!containerMask)
2148 return;
2149
2150 // search world and grid for possible targets
2151 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2152 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2153
2154 if (searchInGrid || searchInWorld)
2155 {
2156 float x, y;
2157 x = pos->GetPositionX();
2158 y = pos->GetPositionY();
2159
2161 Cell cell(p);
2162 cell.SetNoCreate();
2163
2164 Map* map = referer->GetMap();
2165
2166 if (searchInWorld)
2167 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2168
2169 if (searchInGrid)
2170 Cell::VisitGridObjects(x, y, map, searcher, radius);
2171 }
2172}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179

References Acore::ComputeCellCoord(), WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, Cell::SetNoCreate(), Cell::VisitGridObjects(), and Cell::VisitWorldObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
924{
925 if (!targetType.GetTarget())
926 return;
927
928 uint32 effectMask = 1 << effIndex;
929 // set the same target list for all effects
930 // some spells appear to need this, however this requires more research
931 switch (targetType.GetSelectionCategory())
932 {
936 {
937 // targets for effect already selected
938 if (effectMask & processedEffectMask)
939 {
940 return;
941 }
942
943 auto const& effects = GetSpellInfo()->Effects;
944
945 // choose which targets we can select at once
946 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
947 {
948 if (effects[j].IsEffect() &&
949 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
950 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
951 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
952 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
954 {
955 effectMask |= 1 << j;
956 }
957 }
958 processedEffectMask |= effectMask;
959 break;
960 }
961 default:
962 break;
963 }
964
965 switch (targetType.GetSelectionCategory())
966 {
968 SelectImplicitChannelTargets(effIndex, targetType);
969 break;
971 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
972 break;
974 SelectImplicitConeTargets(effIndex, targetType, effectMask);
975 break;
977 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
978 break;
980 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
981 CheckDst();
982
983 SelectImplicitTrajTargets(effIndex, targetType);
984 break;
986 switch (targetType.GetObjectType())
987 {
989 switch (targetType.GetReferenceType())
990 {
993 break;
994 default:
995 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
996 break;
997 }
998 break;
1000 switch (targetType.GetReferenceType())
1001 {
1003 SelectImplicitCasterDestTargets(effIndex, targetType);
1004 break;
1006 SelectImplicitTargetDestTargets(effIndex, targetType);
1007 break;
1009 SelectImplicitDestDestTargets(effIndex, targetType);
1010 break;
1011 default:
1012 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1013 break;
1014 }
1015 break;
1016 default:
1017 switch (targetType.GetReferenceType())
1018 {
1020 SelectImplicitCasterObjectTargets(effIndex, targetType);
1021 break;
1023 SelectImplicitTargetObjectTargets(effIndex, targetType);
1024 break;
1025 default:
1026 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1027 break;
1028 }
1029 break;
1030 }
1031 break;
1033 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1034 break;
1035 default:
1036 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1037 break;
1038 }
1039}
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1718
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1867
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1211
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1681
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1261
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1041
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1804
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1757
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1097
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8702
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1343

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2028{
2029 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2031 switch (m_spellInfo->Effects[effIndex].Effect)
2032 {
2036 {
2038
2040
2041 if (target && target->ToPlayer())
2042 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2043 }
2044 return;
2045 default:
2046 break;
2047 }
2048
2049 // select spell implicit targets based on effect type
2050 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2051 return;
2052
2053 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2054
2055 if (!targetMask)
2056 return;
2057
2058 WorldObject* target = nullptr;
2059
2060 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2061 {
2062 // add explicit object target or self to the target map
2064 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2066 {
2068 target = unitTarget;
2069 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2070 {
2071 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2072 {
2074 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2075 target = owner;
2076 }
2077 }
2078 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2079 target = m_caster;
2080 }
2081 if (targetMask & TARGET_FLAG_ITEM_MASK)
2082 {
2084 AddItemTarget(itemTarget, 1 << effIndex);
2085 return;
2086 }
2087 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2088 target = m_targets.GetGOTarget();
2089 break;
2090 // add self to the target map
2092 if (targetMask & TARGET_FLAG_UNIT_MASK)
2093 target = m_caster;
2094 break;
2095 default:
2096 break;
2097 }
2098
2100
2101 if (target)
2102 {
2103 if (target->ToUnit())
2104 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2105 else if (target->ToGameObject())
2106 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2107 }
2108}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition: SpellInfo.h:72
GameObject * ToGameObject()
Definition: Object.h:210
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:295
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2514
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2381
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2576
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8674
Definition: SpellInfo.h:217

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
784{
785 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
786 if (Unit* target = m_targets.GetUnitTarget())
787 {
788 // check for explicit target redirection, for Grounding Totem for example
792 {
793 Unit* redirect;
794 switch (m_spellInfo->DmgClass)
795 {
798 break;
802 break;
803 default:
804 redirect = nullptr;
805 break;
806 }
807 if (redirect && (redirect != target))
808 {
809 m_targets.SetUnitTarget(redirect);
811 }
812 }
813 }
814}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:10997
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:10959

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1262{
1263 Unit* referer = nullptr;
1264 switch (targetType.GetReferenceType())
1265 {
1269 referer = m_caster;
1270 break;
1272 referer = m_targets.GetUnitTarget();
1273 break;
1275 {
1276 // find last added target for this effect
1277 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1278 {
1279 if (ihit->effectMask & (1 << effIndex))
1280 {
1281 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1282 break;
1283 }
1284 }
1285 break;
1286 }
1287 default:
1288 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1289 return;
1290 }
1291 if (!referer)
1292 return;
1293
1294 Position const* center = nullptr;
1295 switch (targetType.GetReferenceType())
1296 {
1298 center = m_targets.GetSrcPos();
1299 break;
1301 center = m_targets.GetDstPos();
1302 break;
1306 center = referer;
1307 break;
1308 default:
1309 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1310 return;
1311 }
1312
1313 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1314 std::list<WorldObject*> targets;
1315 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1316 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1317
1318 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1319
1320 if (!targets.empty())
1321 {
1322 // Other special target selection goes here
1323 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1324 {
1326 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1327 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1328 maxTargets += (*j)->GetAmount();
1329
1330 Acore::Containers::RandomResize(targets, maxTargets);
1331 }
1332
1333 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1334 {
1335 if (Unit* unitTarget = (*itr)->ToUnit())
1336 AddUnitTarget(unitTarget, effMask, false);
1337 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1338 AddGOTarget(gObjTarget, effMask);
1339 }
1340 }
1341}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition: SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:91
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:79
Position const * GetSrcPos() const
Definition: Spell.cpp:363
float RadiusMod
Definition: Spell.h:215
uint32 MaxAffectedTargets
Definition: Spell.h:214
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8660

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1344{
1346
1347 switch (targetType.GetTarget())
1348 {
1349 case TARGET_DEST_CASTER:
1351 break;
1352 case TARGET_DEST_HOME:
1353 if (Player* playerCaster = m_caster->ToPlayer())
1354 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1355 break;
1356 case TARGET_DEST_DB:
1357 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1358 {
1361 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1362 else if (st->target_mapId == m_caster->GetMapId())
1363 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1364 }
1365 else
1366 {
1367 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1368 if (WorldObject* target = m_targets.GetObjectTarget())
1369 dest = SpellDestination(*target);
1370 }
1371 break;
1373 {
1374 float min_dis = m_spellInfo->GetMinRange(true);
1375 float max_dis = m_spellInfo->GetMaxRange(true);
1376 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1377 float x, y, z, angle;
1378 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1379 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1381
1382 float ground = m_caster->GetMapHeight(x, y, z, true);
1383 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1385 if (liquidData.Status)
1386 liquidLevel = liquidData.Level;
1387
1388 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1389 {
1392 finish(false);
1393 return;
1394 }
1395
1396 if (ground + 0.75 > liquidLevel)
1397 {
1400 finish(false);
1401 return;
1402 }
1403
1404 if (!m_caster->IsWithinLOS(x, y, z))
1405 {
1408 finish(false);
1409 return;
1410 }
1411
1412 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1413 break;
1414 }
1416 {
1417 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1418 Map* map = m_caster->GetMap();
1419 uint32 mapid = m_caster->GetMapId();
1420 uint32 phasemask = m_caster->GetPhaseMask();
1421 float collisionHeight = m_caster->GetCollisionHeight();
1422 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1423
1424 Position pos;
1425 Position lastpos;
1426 m_caster->GetPosition(startx, starty, startz, starto);
1427 pos.Relocate(startx, starty, startz, starto);
1428 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1429 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1430
1431 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
1432
1433 bool isCasterInWater = m_caster->IsInWater();
1434 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1435 {
1436 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1437 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1438 float maxtravelDistZ = 2.65f;
1439 float overdistance = 0.0f;
1440 float totalpath = 0.0f;
1441 float beforewaterz = 0.0f;
1442 bool inwater = false;
1443 bool wcol = false;
1444 const float step = 2.0f;
1445 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1446 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1447 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1448 int j = 1;
1449 for (; j < (numChecks + 1); j++)
1450 {
1451 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1452 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1453 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1454 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1455
1456 if (j < 2)
1457 {
1458 prevZ = pos.GetPositionZ();
1459 }
1460 else
1461 {
1462 prevZ = tstZ;
1463 }
1464
1465 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1466 ground = tstZ;
1467
1468 if (!isCasterInWater)
1469 {
1470 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1471 {
1472 if (!(beforewaterz != 0.0f))
1473 {
1474 beforewaterz = prevZ;
1475 }
1476 tstZ = beforewaterz;
1477 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1478 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1479 }
1480 }
1481 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1482 {
1483 prevZ = pos.GetPositionZ();
1484 tstZ = pos.GetPositionZ();
1485 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1486
1487 inwater = true;
1488 if (inwater && (fabs(tstZ - ground) < 2.0f))
1489 {
1490 wcol = true;
1491 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1492 }
1493
1494 // if (j < 2)
1495 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1496 // else
1497 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1498 }
1499
1500 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1501 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1502 {
1503 if (inwater && !IsInWater)
1504 inwater = false;
1505
1506 // highest available point
1507 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1508 // upper or floor
1509 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1510 //lower than floor
1511 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1512
1513 //distance of rays, will select the shortest in 3D
1514 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1515 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1516 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1517 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1518 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1519 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1520
1521 if (srange1 < srange2)
1522 {
1523 tstZ = tstZ1;
1524 srange = srange1;
1525 }
1526 else if (srange3 < srange2)
1527 {
1528 tstZ = tstZ3;
1529 srange = srange3;
1530 }
1531 else
1532 {
1533 tstZ = tstZ2;
1534 srange = srange2;
1535 }
1536
1537 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1538 }
1539
1540 destx = tstX;
1541 desty = tstY;
1542 destz = tstZ;
1543
1544 totalpath += srange;
1545
1546 if (totalpath > distance)
1547 {
1548 overdistance = totalpath - distance;
1549 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1550 }
1551
1552 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1553 // check dynamic collision
1554 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1555
1556 // collision occured
1557 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1558 {
1559 if ((overdistance > 0.0f) && (overdistance < 1.f))
1560 {
1561 destx = prevX + overdistance * cos(pos.GetOrientation());
1562 desty = prevY + overdistance * sin(pos.GetOrientation());
1563 //LOG_ERROR("spells", "(collision) collision occured 1");
1564 }
1565 else
1566 {
1567 // move back a bit
1568 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1569 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1570 //LOG_ERROR("spells", "(collision) collision occured 2");
1571 }
1572
1573 // highest available point
1574 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1575 // upper or floor
1576 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1577 //lower than floor
1578 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1579
1580 //distance of rays, will select the shortest in 3D
1581 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1582 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1583 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1584
1585 if (srange1 < srange2)
1586 destz = destz1;
1587 else if (srange3 < srange2)
1588 destz = destz3;
1589 else
1590 destz = destz2;
1591
1592 if (inwater && destz < prevZ && !wcol)
1593 destz = prevZ;
1594 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1595
1596 // Don't make the player move backward from the xy adjustments by collisions.
1597 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1598 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1599 {
1600 destx = startx;
1601 desty = starty;
1602 destz = startz;
1603 }
1604
1605 break;
1606 }
1607 // we have correct destz now
1608 }
1609
1610 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1611 dest = SpellDestination(lastpos);
1612 }
1613 else
1614 {
1615 float z = pos.GetPositionZ();
1616 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1617 // check dynamic collision
1618 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1619
1620 // collision occured
1621 if (col || dcol)
1622 {
1623 // move back a bit
1624 destx = destx - (0.6 * cos(pos.GetOrientation()));
1625 desty = desty - (0.6 * sin(pos.GetOrientation()));
1626 }
1627
1628 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1629 dest = SpellDestination(lastpos);
1630 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1631 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1632 }
1633 break;
1634 }
1635 default:
1636 {
1637 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1638 float angle = targetType.CalcDirectionAngle();
1639 float objSize = m_caster->GetCombatReach();
1640
1641 switch (targetType.GetTarget())
1642 {
1644 dist = PET_FOLLOW_DIST;
1645 break;
1647 if (dist > objSize)
1648 dist = objSize + (dist - objSize) * float(rand_norm());
1649 break;
1654 {
1655 static float const DefaultTotemDistance = 3.0f;
1656 if (!m_spellInfo->Effects[effIndex].HasRadius())
1657 dist = DefaultTotemDistance;
1658 break;
1659 }
1660 default:
1661 break;
1662 }
1663
1664 if (dist < objSize)
1665 {
1666 dist = objSize;
1667 }
1668
1669 Position pos = dest._position;
1670 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1671
1672 dest.Relocate(pos);
1673 break;
1674 }
1675 }
1676
1677 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1678 m_targets.SetDst(dest);
1679}
#define MAP_ALL_LIQUIDS
Definition: Map.h:160
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:356
@ SPELL_EFFECT_BIND
Definition: SharedDefines.h:789
@ SPELL_EFFECT_TELEPORT_UNITS
Definition: SharedDefines.h:783
@ TARGET_DEST_CASTER_RANDOM
Definition: SharedDefines.h:1476
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition: SharedDefines.h:1459
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition: SharedDefines.h:1448
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition: SharedDefines.h:1446
@ TARGET_DEST_CASTER_FISHING
Definition: SharedDefines.h:1443
@ TARGET_DEST_CASTER_BACK_LEFT
Definition: SharedDefines.h:1447
@ TARGET_DEST_CASTER_SUMMON
Definition: SharedDefines.h:1436
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition: SharedDefines.h:1445
@ TARGET_DEST_CASTER_36
Definition: SharedDefines.h:1440
@ TARGET_DEST_HOME
Definition: SharedDefines.h:1418
@ SPELL_FAILED_TOO_SHALLOW
Definition: SharedDefines.h:1105
#define VMAP_INVALID_HEIGHT_VALUE
Definition: IVMapMgr.h:49
static VMapMgr2 * createOrGetVMapMgr()
Definition: VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition: VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3115
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2623
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21020
Definition: Map.h:171
float Level
Definition: Map.h:176
LiquidStatus Status
Definition: Map.h:178
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:2040
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition: Map.cpp:2201
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2500
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:2478
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8688
Definition: SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1758{
1759 WorldObject* target = nullptr;
1760 bool checkIfValid = true;
1761
1762 switch (targetType.GetTarget())
1763 {
1764 case TARGET_UNIT_CASTER:
1765 target = m_caster;
1766 checkIfValid = false;
1767 break;
1768 case TARGET_UNIT_MASTER:
1769 target = m_caster->GetCharmerOrOwner();
1770 break;
1771 case TARGET_UNIT_PET:
1772 target = m_caster->GetGuardianPet();
1773 if (!target)
1774 target = m_caster->GetCharm();
1775 break;
1777 if (m_caster->IsSummon())
1778 target = m_caster->ToTempSummon()->GetSummonerUnit();
1779 break;
1781 target = m_caster->GetVehicleBase();
1782 break;
1792 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1793 break;
1794 default:
1795 break;
1796 }
1797
1798 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1799
1800 if (target && target->ToUnit())
1801 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1802}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1501
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1506
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1504
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1507
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1503
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1500
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition: Unit.cpp:18670
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:224

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1827{
1828 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1829 if (Player* modOwner = m_caster->GetSpellModOwner())
1830 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1831
1832 if (maxTargets > 1)
1833 {
1834 // mark damage multipliers as used
1835 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1836 if (effMask & (1 << k))
1837 m_damageMultipliers[k] = 1.0f;
1838 m_applyMultiplierMask |= effMask;
1839
1840 std::list<WorldObject*> targets;
1841 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1842 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1843
1844 // Chain primary target is added earlier
1845 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1846
1847 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1848 if (Unit* unitTarget = (*itr)->ToUnit())
1849 AddUnitTarget(unitTarget, effMask, false);
1850 }
1851}
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:94
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1449
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2196

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1042{
1043 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1044 {
1045 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1046 return;
1047 }
1048
1049 switch (targetType.GetTarget())
1050 {
1052 {
1053 // Xinef: All channel selectors have needed data passed in m_targets structure
1055 if (target)
1056 {
1057 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1058 // unit target may be no longer avalible - teleported out of map for example
1059 if (target && target->ToUnit())
1060 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1061 }
1062 else
1063 {
1064 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1065 }
1066 break;
1067 }
1072 {
1073 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1074 if (target)
1075 m_targets.SetDst(*target);
1076 }
1078 {
1079 if (channeledSpell->m_targets.GetUnitTarget())
1080 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1081 }
1082 else //if (!m_targets.HasDst())
1083 {
1084 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1085 }
1086 break;
1088 if (GetOriginalCaster())
1090 break;
1091 default:
1092 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1093 break;
1094 }
1095}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1480
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1481
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1510
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:465
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:475
bool HasDstChannel() const
Definition: Spell.cpp:470

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1212{
1213 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1214 {
1215 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1216 return;
1217 }
1218 std::list<WorldObject*> targets;
1219 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1220 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1221 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1222 float coneAngle = M_PI / 2;
1223 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1224
1225 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1226 {
1227 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1228 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1229 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1230
1231 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1232
1233 if (!targets.empty())
1234 {
1235 // Other special target selection goes here
1236 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1237 {
1239 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1240 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1241 maxTargets += (*j)->GetAmount();
1242
1243 Acore::Containers::RandomResize(targets, maxTargets);
1244 }
1245
1246 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1247 {
1248 if (Unit* unit = (*itr)->ToUnit())
1249 {
1250 AddUnitTarget(unit, effMask, false);
1251 }
1252 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1253 {
1254 AddGOTarget(gObjTarget, effMask);
1255 }
1256 }
1257 }
1258 }
1259}
SpellTargetCheckTypes
Definition: SpellInfo.h:113
SpellTargetObjectTypes
Definition: SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1719{
1720 // set destination to caster if no dest provided
1721 // can only happen if previous destination target could not be set for some reason
1722 // (not found nearby target, or channel target for example
1723 // maybe we should abort the spell in such case?
1724 CheckDst();
1725
1727
1728 switch (targetType.GetTarget())
1729 {
1733 case TARGET_DEST_DEST:
1734 return;
1735 case TARGET_DEST_TRAJ:
1736 SelectImplicitTrajTargets(effIndex, targetType);
1737 return;
1738 default:
1739 {
1740 float angle = targetType.CalcDirectionAngle();
1741 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1742 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1743 dist *= float(rand_norm());
1744
1745 Position pos = dest._position;
1746 m_caster->MovePosition(pos, dist, angle);
1747
1748 dest.Relocate(pos);
1749 break;
1750 }
1751 }
1752
1753 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1754 m_targets.ModDst(dest);
1755}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1490
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1433
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
void MovePosition(Position &pos, float dist, float angle)
Definition: Object.cpp:2773
void ModDst(Position const &pos)
Definition: Spell.cpp:437
SpellDestination const * GetDst() const
Definition: Spell.cpp:397

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1098{
1099 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1100 {
1101 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1102 return;
1103 }
1104
1105 float range = 0.0f;
1106 switch (targetType.GetCheckType())
1107 {
1108 case TARGET_CHECK_ENEMY:
1109 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1110 break;
1111 case TARGET_CHECK_ALLY:
1112 case TARGET_CHECK_PARTY:
1113 case TARGET_CHECK_RAID:
1115 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1116 break;
1117 case TARGET_CHECK_ENTRY:
1120 break;
1121 default:
1122 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1123 break;
1124 }
1125
1126 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1127
1128 // handle emergency case - try to use other provided targets if no conditions provided
1129 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1130 {
1131 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1132 switch (targetType.GetObjectType())
1133 {
1136 {
1137 if (focusObject)
1138 AddGOTarget(focusObject, effMask);
1139 return;
1140 }
1141 break;
1144 {
1145 if (focusObject)
1147 return;
1148 }
1149 break;
1150 default:
1151 break;
1152 }
1153 }
1154
1155 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1156 if (!target)
1157 {
1158 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1159 return;
1160 }
1161
1162 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1163 if (!target)
1164 {
1165 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1166 return;
1167 }
1168
1169 switch (targetType.GetObjectType())
1170 {
1172 {
1173 if (Unit* unit = target->ToUnit())
1174 {
1175 AddUnitTarget(unit, effMask, true, false);
1176 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1177 // and if channeled spell has target 77, it requires unitTarget, set it here!
1178 // xinef: if we have NO unit target
1179 if (!m_targets.GetUnitTarget())
1180 {
1182 }
1183 }
1184 else
1185 {
1186 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1187 return;
1188 }
1189 break;
1190 }
1192 if (GameObject* gobjTarget = target->ToGameObject())
1193 AddGOTarget(gobjTarget, effMask);
1194 else
1195 {
1196 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1197 return;
1198 }
1199 break;
1201 m_targets.SetDst(*target);
1202 break;
1203 default:
1204 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1205 break;
1206 }
1207
1208 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1209}
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition: Spell.cpp:2174
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1826

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1682{
1684
1685 SpellDestination dest(*target);
1686
1687 switch (targetType.GetTarget())
1688 {
1691 break;
1692 default:
1693 {
1694 float angle = targetType.CalcDirectionAngle();
1695 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1696 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1697 {
1698 dist *= float(rand_norm());
1699 }
1700
1701 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1702 {
1704 }
1705
1706 Position pos = dest._position;
1707 target->MovePositionToFirstCollision(pos, dist, angle);
1708
1709 dest.Relocate(pos);
1710 break;
1711 }
1712 }
1713
1714 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1715 m_targets.SetDst(dest);
1716}
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1469
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1478
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1805{
1806 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1807
1809
1810 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1811
1812 if (target)
1813 {
1814 if (Unit* unit = target->ToUnit())
1815 AddUnitTarget(unit, 1 << effIndex, true, false);
1816 else if (GameObject* gobj = target->ToGameObject())
1817 AddGOTarget(gobj, 1 << effIndex);
1818
1819 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1820 }
1821 // Script hook can remove object target and we would wrongly land here
1822 else if (Item* item = m_targets.GetItemTarget())
1823 AddItemTarget(item, 1 << effIndex);
1824}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1868{
1869 if (!m_targets.HasTraj())
1870 return;
1871
1872 float dist2d = m_targets.GetDist2d();
1873 if (!dist2d)
1874 return;
1875
1876 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1877
1878 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1879 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1880 std::list<WorldObject*> targets;
1881 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1883 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1884 if (targets.empty())
1885 return;
1886
1888
1889 float b = tangent(m_targets.GetElevation());
1890 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1891 if (a > -0.0001f)
1892 a = 0;
1893
1894 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1895
1896 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1897 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1898 if (bestDist < 1.0f)
1899 bestDist = 300.0f;
1900
1901 std::list<WorldObject*>::const_iterator itr = targets.begin();
1902 for (; itr != targets.end(); ++itr)
1903 {
1904 if (Unit* unitTarget = (*itr)->ToUnit())
1905 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1906 continue;
1907
1908 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1910 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1911 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1912
1913 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1914 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1915
1916 float dist = objDist2d - size;
1917 float height = dist * (a * dist + b);
1918
1919 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1920
1921 if (dist < bestDist && height < dz + size && height > dz - size)
1922 {
1923 bestDist = dist > 0 ? dist : 0;
1924 break;
1925 }
1926
1927#define CHECK_DIST {\
1928 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1929 if (dist > bestDist)\
1930 continue;\
1931 if (dist < objDist2d + size && dist > objDist2d - size)\
1932 {\
1933 bestDist = dist;\
1934 break;\
1935 }\
1936 }
1937
1938 // RP-GG only, search in straight line, as item have no trajectory
1939 if (m_CastItem)
1940 {
1941 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1942 {
1943 bestDist = dist;
1944 break;
1945 }
1946
1947 continue;
1948 }
1949
1950 if (!a)
1951 {
1952 // Xinef: everything remade
1953 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1954 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1955
1956 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1957 {
1958 bestDist = dist;
1959 break;
1960 }
1961
1962 continue;
1963 }
1964
1965 height = dz - size;
1966 float sqrt1 = b * b + 4 * a * height;
1967 if (sqrt1 > 0)
1968 {
1969 sqrt1 = std::sqrt(sqrt1);
1970 dist = (sqrt1 - b) / (2 * a);
1971 CHECK_DIST;
1972 }
1973
1974 height = dz + size;
1975 float sqrt2 = b * b + 4 * a * height;
1976 if (sqrt2 > 0)
1977 {
1978 sqrt2 = std::sqrt(sqrt2);
1979 dist = (sqrt2 - b) / (2 * a);
1980 CHECK_DIST;
1981
1982 dist = (-sqrt2 - b) / (2 * a);
1983 CHECK_DIST;
1984 }
1985
1986 if (sqrt1 > 0)
1987 {
1988 dist = (-sqrt1 - b) / (2 * a);
1989 CHECK_DIST;
1990 }
1991 }
1992
1994 {
1995 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
1996 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
1997 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1998
1999 if (itr != targets.end())
2000 {
2001 float distSq = (*itr)->GetExactDistSq(x, y, z);
2002 float sizeSq = (*itr)->GetObjectSize();
2003 sizeSq *= sizeSq;
2004 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2005 if (distSq > sizeSq)
2006 {
2007 float factor = 1 - std::sqrt(sizeSq / distSq);
2008 x += factor * ((*itr)->GetPositionX() - x);
2009 y += factor * ((*itr)->GetPositionY() - y);
2010 z += factor * ((*itr)->GetPositionZ() - z);
2011
2012 distSq = (*itr)->GetExactDistSq(x, y, z);
2013 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2014 }
2015 }
2016
2017 Position trajDst;
2018 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2020 dest.Relocate(trajDst);
2021
2022 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2023 m_targets.ModDst(dest);
2024 }
2025}
float tangent(float x)
Definition: Spell.cpp:1853
#define CHECK_DIST
Definition: Object.h:696
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1698
float GetElevation() const
Definition: Spell.h:168

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
817{
818 // select targets for cast phase
820
821 uint32 processedAreaEffectsMask = 0;
822 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
823 {
824 // not call for empty effect.
825 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
826 if (!m_spellInfo->Effects[i].IsEffect())
827 continue;
828
829 // set expected type of implicit targets to be sent to client
830 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
831 if (implicitTargetMask & TARGET_FLAG_UNIT)
833 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
835
836 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
837 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
838
839 // Select targets of effect based on effect type
840 // those are used when no valid target could be added for spell effect based on spell target type
841 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
842 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
843 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
845
846 if (m_targets.HasDst())
848
850 {
851 // maybe do this for all spells?
852 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
853 {
855 finish(false);
856 return;
857 }
858
859 uint8 mask = (1 << i);
860 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
861 {
862 if (ihit->effectMask & mask)
863 {
865 break;
866 }
867 }
868 }
869 else if (m_auraScaleMask)
870 {
871 bool checkLvl = !m_UniqueTargetInfo.empty();
872 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
873 {
874 // remove targets which did not pass min level check
875 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
876 {
877 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
878 return true;
879 }
880
881 return false;
882 }), std::end(m_UniqueTargetInfo));
883
884 if (checkLvl && m_UniqueTargetInfo.empty())
885 {
887 finish(false);
888 }
889 }
890 }
891
892 if (uint64 dstDelay = CalculateDelayMomentForDst())
893 m_delayMoment = dstDelay;
894}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:30
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition: Spell.h:120
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition: Spell.cpp:923
void SelectExplicitTargets()
Definition: Spell.cpp:783
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2605
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2027

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4661{
4662 if (result == SPELL_CAST_OK)
4663 return;
4664
4665 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4666 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4667
4668 caster->GetSession()->SendPacket(&data);
4669}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4555

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4672{
4673 if (result == SPELL_CAST_OK)
4674 return;
4675
4676 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4677 return;
4678
4679 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4680 return;
4681
4682 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4684 result = SPELL_FAILED_DONT_REPORT;
4685
4687}
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:147
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1108
bool IsCharmed() const
Definition: Unit.h:1214

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5198{
5199 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5200 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5201 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5202 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5203
5204 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5205 data << m_caster->GetPackGUID();
5206 data << uint32(m_spellInfo->Id);
5207 data << uint32(duration);
5208
5209 m_caster->SendMessageToSet(&data, true);
5210
5213
5214 m_timer = duration;
5215 if (channelTarget)
5217
5219}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5166{
5167 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5168 data << m_caster->GetPackGUID();
5169 data << uint8(m_cast_count);
5170 data << uint32(m_spellInfo->Id);
5171 data << uint8(result);
5172 m_caster->SendMessageToSet(&data, true);
5173
5174 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5175 data << m_caster->GetPackGUID();
5176 data << uint8(m_cast_count);
5177 data << uint32(m_spellInfo->Id);
5178 data << uint8(result);
5179 m_caster->SendMessageToSet(&data, true);
5180}
@ SMSG_SPELL_FAILURE
Definition: Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition: Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5065{
5066 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5067
5068 data << m_caster->GetPackGUID();
5069
5070 data << uint32(m_spellInfo->Id);
5071
5072 uint8 effCount = 0;
5073 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5074 {
5075 if (m_effectExecuteData[i])
5076 ++effCount;
5077 }
5078
5079 if (!effCount)
5080 return;
5081
5082 data << uint32(effCount);
5083 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5084 {
5085 if (!m_effectExecuteData[i])
5086 continue;
5087
5088 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5089
5090 data.append(*m_effectExecuteData[i]);
5091
5092 delete m_effectExecuteData[i];
5093 m_effectExecuteData[i] = nullptr;
5094 }
5095 m_caster->SendMessageToSet(&data, true);
5096}
@ SMSG_SPELLLOGEXECUTE
Definition: Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
1998{
1999 Player* player = m_caster->ToPlayer();
2000 if (!player)
2001 return;
2002
2003 if (gameObjTarget)
2004 {
2005 // Players shouldn't be able to loot gameobjects that are currently despawned
2006 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2007 {
2008 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2009 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2010 return;
2011 }
2012 // special case, already has GossipHello inside so return and avoid calling twice
2014 {
2016 return;
2017 }
2018
2019 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2020 return;
2021
2022 if (gameObjTarget->AI()->GossipHello(player, false))
2023 return;
2024
2025 switch (gameObjTarget->GetGoType())
2026 {
2028 gameObjTarget->UseDoorOrButton(0, false, player);
2029 return;
2031 gameObjTarget->UseDoorOrButton(0, false, player);
2032
2033 // Xinef: properly link possible traps
2034 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2035 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2036 return;
2040 return;
2041
2043 // triggering linked GO
2046 return;
2047
2049 // triggering linked GO
2050 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2052
2053 // Don't return, let loots been taken
2054 default:
2055 break;
2056 }
2057 }
2058
2059 // Send loot
2060 player->SendLoot(guid, loottype);
2061}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1568
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1562
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:55
bool isSpawned() const
Definition: GameObject.h:190
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1385
uint32 gossipID
Definition: GameObjectData.h:73
uint32 linkedTrap
Definition: GameObjectData.h:60
struct GameObjectTemplate::@227::@232 chest
struct GameObjectTemplate::@227::@236 spellFocus
uint32 linkedTrapId
Definition: GameObjectData.h:91
struct GameObjectTemplate::@227::@231 questgiver
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4690{
4691 if (result == SPELL_CAST_OK)
4692 return;
4693
4694 Unit* owner = m_caster->GetCharmerOrOwner();
4695 if (!owner)
4696 return;
4697
4698 Player* player = owner->ToPlayer();
4699 if (!player)
4700 return;
4701
4702 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4704
4705 player->GetSession()->SendPacket(&data);
4706}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5222{
5223 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5224 // for player resurrections the name is looked up by guid
5225 std::string const sentName(m_caster->IsPlayer()
5226 ? ""
5228
5229 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5230 data << m_caster->GetGUID();
5231 data << uint32(sentName.size() + 1);
5232
5233 data << sentName;
5234 data << uint8(0); // null terminator
5235
5236 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5237 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5239 data << uint32(0);
5240 target->GetSession()->SendPacket(&data);
5241}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:497
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:461
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:498

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4347{
4348 // xinef: properly add creature cooldowns
4349 if (!m_caster->IsPlayer())
4350 {
4352 {
4353 // xinef: this should be added here
4354 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4355
4356 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4359 {
4360 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4361 data << m_caster->GetGUID();
4363 data << uint32(m_spellInfo->Id);
4365 player->SendDirectMessage(&data);
4366 }
4367 }
4368 return;
4369 }
4370
4371 Player* _player = m_caster->ToPlayer();
4372
4373 // mana/health/etc potions, disabled by client (until combat out as declarate)
4375 {
4376 // need in some way provided data for Spell::finish SendCooldownEvent
4377 _player->SetLastPotionId(m_CastItem->GetEntry());
4378 return;
4379 }
4380
4381 // have infinity cooldown but set at aura apply
4382 // do not set cooldown for triggered spells (needed by reincarnation)
4387 return;
4388
4390}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:617
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1790
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10864
uint32 RecoveryTime
Definition: SpellInfo.h:348
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1181

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4789{
4790 // not send invisible spell casting
4791 if (!IsNeedSendToClient(true))
4792 return;
4793
4794 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4795
4796 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4797
4798 // triggered spells with spell visual != 0
4800 castFlags |= CAST_FLAG_PENDING;
4801
4803 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4804
4805 // should only be sent to self, but the current messaging doesn't make that possible
4806 if (m_caster->IsPlayer() || m_caster->IsPet())
4807 {
4808 switch (m_spellInfo->PowerType)
4809 {
4810 case POWER_HEALTH:
4811 break;
4812 case POWER_RUNE:
4813 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4814 break;
4815 default:
4816 if (m_powerCost != 0)
4817 {
4818 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4819 }
4820 break;
4821 }
4822 }
4823
4824 if ((m_caster->IsPlayer())
4828 {
4829 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4830 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4831 }
4832
4834 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4835
4836 if (m_targets.HasTraj())
4837 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4838
4840 castFlags |= CAST_FLAG_NO_GCD;
4841
4842 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4843 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4844 {
4845 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4846 {
4847 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4848 {
4849 realCasterGUID = casterGameobject->GetPackGUID();
4850 }
4851 }
4852 }
4853
4854 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4855
4856 if (m_CastItem)
4857 data << m_CastItem->GetPackGUID();
4858 else
4859 data << realCasterGUID;
4860
4861 data << realCasterGUID;
4862 data << uint8(m_cast_count); // pending spell cast?
4863 data << uint32(m_spellInfo->Id); // spellId
4864 data << uint32(castFlags); // cast flags
4865 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4866
4867 WriteSpellGoTargets(&data);
4868
4869 m_targets.Write(data);
4870
4871 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4873
4874 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4875 {
4876 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4877 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4878 if (Player* player = m_caster->ToPlayer())
4879 {
4880 uint8 runeMaskInitial = m_runesState;
4881 uint8 runeMaskAfterCast = player->GetRunesState();
4882 data << uint8(runeMaskInitial); // runes state before
4883 data << uint8(runeMaskAfterCast); // runes state after
4884 for (uint8 i = 0; i < MAX_RUNES; ++i)
4885 {
4886 uint8 mask = (1 << i);
4887 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4888 {
4889 // float casts ensure the division is performed on floats as we need float result
4890 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4891 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4892 }
4893 }
4894 }
4895 }
4896 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4897 {
4898 data << m_targets.GetElevation();
4900 }
4901
4902 if (castFlags & CAST_FLAG_PROJECTILE)
4903 WriteAmmoToPacket(&data);
4904
4905 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4906 {
4907 data << uint32(0);
4908 data << uint32(0);
4909 }
4910
4912 {
4913 data << uint8(0);
4914 }
4915
4916 m_caster->SendMessageToSet(&data, true);
4917}
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:63
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:61
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:52
@ CAST_FLAG_NO_GCD
Definition: Spell.h:62
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:49
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:55
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:65
@ CAST_FLAG_PENDING
Definition: Spell.h:44
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:924
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:383
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition: Spell.cpp:180
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:5004
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4919
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8082
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:347
int32 CastTime
Definition: DBCStructure.h:1760

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4709{
4710 if (!IsNeedSendToClient(false))
4711 return;
4712
4713 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4714
4715 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4716
4718 castFlags |= CAST_FLAG_PENDING;
4719
4721 castFlags |= CAST_FLAG_PROJECTILE;
4722
4723 if (m_caster->IsPlayer() || m_caster->IsPet())
4724 {
4725 switch (m_spellInfo->PowerType)
4726 {
4727 case POWER_HEALTH:
4728 break;
4729 case POWER_RUNE:
4730 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4731 break;
4732 default:
4733 if (m_powerCost != 0)
4734 {
4735 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4736 }
4737 break;
4738 }
4739 }
4740
4742 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4743
4744 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4745 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4746 {
4747 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4748 {
4749 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4750 {
4751 realCasterGUID = casterGameobject->GetPackGUID();
4752 }
4753 }
4754 }
4755
4756 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4757 if (m_CastItem)
4758 data << m_CastItem->GetPackGUID();
4759 else
4760 data << realCasterGUID;
4761
4762 data << realCasterGUID;
4763 data << uint8(m_cast_count); // pending spell cast?
4764 data << uint32(m_spellInfo->Id); // spellId
4765 data << uint32(castFlags); // cast flags
4766 data << int32(m_timer); // delay?
4767
4768 m_targets.Write(data);
4769
4770 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4772
4773 if (castFlags & CAST_FLAG_PROJECTILE)
4774 WriteAmmoToPacket(&data);
4775
4776 if (castFlags & CAST_FLAG_UNKNOWN_23)
4777 {
4778 data << uint32(0);
4779 data << uint32(0);
4780 }
4781
4782 m_caster->SendMessageToSet(&data, true);
4783
4786}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:66
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:45
@ SMSG_SPELL_START
Definition: Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
549{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
563{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
561{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8424{
8425 switch (mod)
8426 {
8428 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8429 break;
8431 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8432 break;
8434 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8435 break;
8437 m_spellValue->RadiusMod = (float)value / 10000;
8438 break;
8441 break;
8444 break;
8446 m_spellValue->AuraDuration = value;
8447 break;
8449 m_spellValue->ForcedCritResult = (bool)value;
8450 break;
8451 }
8452}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:119
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:120
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:117
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:118
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:121
bool ForcedCritResult
Definition: Spell.h:218

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
483{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5933{
5934 Unit* caster = m_originalCaster;
5935 if (!caster)
5936 return;
5937
5938 if (caster->IsTotem())
5939 caster = caster->ToTotem()->GetOwner();
5940
5941 // in another case summon new
5942 uint8 summonLevel = caster->GetLevel();
5943
5944 // level of pet summoned using engineering item based at engineering skill level
5945 if (m_CastItem && caster->IsPlayer())
5946 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5947 {
5948 // xinef: few special cases
5949 if (proto->RequiredSkill == SKILL_ENGINEERING)
5950 {
5951 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5952 summonLevel = skill202 / 5;
5953 }
5954
5955 switch (m_spellInfo->Id)
5956 {
5957 // Dragon's Call
5958 case 13049:
5959 summonLevel = 55;
5960 break;
5961
5962 // Cleansed Timberling Heart: Summon Timberling
5963 case 5666:
5964 summonLevel = 7;
5965 break;
5966
5967 // Glowing Cat Figurine: Summon Ghost Saber
5968 case 6084:
5969 // minLevel 19, maxLevel 20
5970 summonLevel = 20;
5971 break;
5972
5973 // Spiked Collar: Summon Felhunter
5974 case 8176:
5975 summonLevel = 30;
5976 break;
5977
5978 // Dog Whistle: Summon Tracking Hound
5979 case 9515:
5980 summonLevel = 30;
5981 break;
5982
5983 // Barov Peasant Caller: Death by Peasant
5984 case 18307:
5985 case 18308:
5986 summonLevel = 60;
5987 break;
5988
5989 // Thornling Seed: Plant Thornling
5990 case 22792:
5991 summonLevel = 60;
5992 break;
5993
5994 // Cannonball Runner: Summon Crimson Cannon
5995 case 6251:
5996 summonLevel = 61;
5997 break;
5998 }
5999 }
6000
6001 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6002
6003 float radius = 5.0f;
6004 int32 duration = m_spellInfo->GetDuration();
6005
6006 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6007 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6008
6009 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6010 Map* map = caster->GetMap();
6011 TempSummon* summon = nullptr;
6012
6013 uint32 currMinionsCount = m_caster->m_Controlled.size();
6014 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6015
6016 for (uint32 count = 0; count < numGuardians; ++count)
6017 {
6018 Position pos;
6019
6020 // xinef: do not use precalculated position for effect summon pet in this function
6021 // it means it was cast by NPC and should have its position overridden unless the
6022 // target position is specified in the DB AND the effect has no or zero radius
6023 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6024 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6025 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6026 {
6027 pos = *destTarget;
6028 }
6029 else
6030 {
6031 // randomize position
6032 pos = m_caster->GetRandomPoint(*destTarget, radius);
6033 }
6034
6035 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6036 if (!summon)
6037 return;
6038
6039 // xinef: set calculated level
6040 summon->SetLevel(summonLevel);
6041
6042 // if summonLevel changed, set stats for calculated level
6043 if (summonLevel != caster->GetLevel())
6044 {
6045 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6046 }
6047
6048 // xinef: if we have more than one guardian, change follow angle
6049 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6050 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6051 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6052 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6053
6054 // xinef: move this here, some auras are added in initstatsforlevel!
6055 if (!summon->IsInCombat() && !summon->IsTrigger())
6056 {
6057 // summon->AI()->EnterEvadeMode();
6058 summon->GetMotionMaster()->Clear(false);
6060 }
6061
6062 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6063 summon->SetFaction(caster->GetFaction());
6064
6066 }
6067
6068 // Summon infernal, cast enslave demon
6069 // xinef: have to do it here because in Pet init stats infernal is not in world, imo this should be changed...
6070 if (summon)
6071 {
6072 switch (m_spellInfo->Id)
6073 {
6074 // Inferno, Warlock summon spell
6075 case 1122:
6076 caster->AddAura(61191, summon);
6077 break;
6078 // Ritual of Doom, Warlock summon spell
6079 case 60478:
6080 caster->AddAura(SPELL_RITUAL_ENSLAVEMENT, summon);
6081 break;
6082 }
6083 }
6084}
@ SPELL_RITUAL_ENSLAVEMENT
Definition: PetDefines.h:155
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:240
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:290
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
bool IsTrigger() const
Definition: Creature.h:78
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15398

References Unit::AddAura(), SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELL_RITUAL_ENSLAVEMENT, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5371{
5373 {
5375
5376 // wands don't have ammo
5377 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5378 return;
5379
5380 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5381 {
5382 if (pItem->GetMaxStackCount() == 1)
5383 {
5384 // decrease durability for non-stackable throw weapon
5386 }
5387 else
5388 {
5389 // decrease items amount for stackable throw weapon
5390 uint32 count = 1;
5391 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5392 }
5393 }
5395 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5396 }
5397}
@ INVTYPE_THROWN
Definition: ItemTemplate.h:281
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:692
uint32 GetMaxStackCount() const
Definition: Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4761

References Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, ItemTemplate::SubClass, and Object::ToPlayer().

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5244{
5245 if (!m_CastItem || !m_caster->IsPlayer())
5246 return;
5247
5248 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5250 return;
5251
5252 ItemTemplate const* proto = m_CastItem->GetTemplate();
5253
5254 if (!proto)
5255 {
5256 // This code is to avoid a crash
5257 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5258 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5259 return;
5260 }
5261
5262 bool expendable = false;
5263 bool withoutCharges = false;
5264
5265 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5266 {
5267 if (proto->Spells[i].SpellId)
5268 {
5269 // item has limited charges
5270 if (proto->Spells[i].SpellCharges)
5271 {
5272 if (proto->Spells[i].SpellCharges < 0)
5273 expendable = true;
5274
5275 int32 charges = m_CastItem->GetSpellCharges(i);
5276
5277 // item has charges left
5278 if (charges)
5279 {
5280 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5281 if (proto->Stackable == 1)
5282 m_CastItem->SetSpellCharges(i, charges);
5284 }
5285
5286 // all charges used
5287 withoutCharges = (charges == 0);
5288 }
5289 }
5290 }
5291
5292 if (expendable && withoutCharges)
5293 {
5294 uint32 count = 1;
5295 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5296
5297 // prevent crash at access to deleted m_targets.GetItemTarget
5299 m_targets.SetItemTarget(nullptr);
5300
5301 m_CastItem = nullptr;
5303 }
5304}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:318
int32 Stackable
Definition: ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5307{
5309 return;
5310
5311 //Don't take power if the spell is cast while .cheat power is enabled.
5312 if (m_caster->IsPlayer())
5314 return;
5315
5317 bool hit = true;
5318 if (m_caster->IsPlayer())
5319 {
5321 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5322 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5323 if (ihit->targetGUID == targetGUID)
5324 {
5325 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5326 {
5327 hit = false;
5328 //lower spell cost on fail (by talent aura)
5329 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5330 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5331 }
5332 break;
5333 }
5334 }
5335
5336 if (PowerType == POWER_RUNE)
5337 {
5338 TakeRunePower(hit);
5339 return;
5340 }
5341
5342 if (!m_powerCost)
5343 return;
5344
5345 // health as power used
5346 if (PowerType == POWER_HEALTH)
5347 {
5349 return;
5350 }
5351
5352 if (PowerType >= MAX_POWERS)
5353 {
5354 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5355 return;
5356 }
5357
5358 if (hit)
5360 else
5362
5363 // Set the five second timer
5364 if (PowerType == POWER_MANA && m_powerCost > 0)
5365 {
5367 }
5368}
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:107
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1529
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14031
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:1560
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5453

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5523{
5524 if (!m_caster->IsPlayer())
5525 return;
5526
5527 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5528
5529 // do not take reagents for these item casts
5530 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5531 return;
5532
5533 Player* p_caster = m_caster->ToPlayer();
5534 if (p_caster->CanNoReagentCast(m_spellInfo))
5535 return;
5536
5537 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5538 {
5539 if (m_spellInfo->Reagent[x] <= 0)
5540 continue;
5541
5542 uint32 itemid = m_spellInfo->Reagent[x];
5543 uint32 itemcount = m_spellInfo->ReagentCount[x];
5544
5545 // if CastItem is also spell reagent
5546 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5547 {
5548 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5549 {
5550 // CastItem will be used up and does not count as reagent
5551 int32 charges = m_CastItem->GetSpellCharges(s);
5552 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5553 {
5554 ++itemcount;
5555 break;
5556 }
5557 }
5558
5559 m_CastItem = nullptr;
5561 }
5562
5563 // if GetItemTarget is also spell reagent
5564 if (m_targets.GetItemTargetEntry() == itemid)
5565 m_targets.SetItemTarget(nullptr);
5566
5567 p_caster->DestroyItemCount(itemid, itemcount, true);
5568 }
5569}
uint32 ItemId
Definition: ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5454{
5456 return;
5457
5458 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5459 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5460 return;
5461
5462 Player* player = m_caster->ToPlayer();
5463 m_runesState = player->GetRunesState(); // store previous state
5464
5465 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5466
5467 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5468 {
5469 runeCost[i] = runeCostData->RuneCost[i];
5470 if (Player* modOwner = m_caster->GetSpellModOwner())
5471 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5472 }
5473
5474 runeCost[RUNE_DEATH] = 0; // calculated later
5475
5476 for (uint32 i = 0; i < MAX_RUNES; ++i)
5477 {
5478 RuneType rune = player->GetCurrentRune(i);
5479 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5480 {
5481 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5482 player->SetLastUsedRune(rune);
5483 runeCost[rune]--;
5484 }
5485 }
5486
5487 // Xinef: firstly consume death runes of base type
5488 // Xinef: in second loop consume all available
5489 for (uint8 loop = 0; loop < 2; ++loop)
5490 {
5491 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5492 if (runeCost[RUNE_DEATH] > 0)
5493 {
5494 for (uint8 i = 0; i < MAX_RUNES; ++i)
5495 {
5496 RuneType rune = player->GetCurrentRune(i);
5497 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5498 {
5499 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5500 player->SetLastUsedRune(rune);
5501 runeCost[rune]--;
5502 if (!loop)
5503 runeCost[player->GetBaseRune(i)]--;
5504
5505 // keep Death Rune type if missed
5506 if (didHit)
5507 player->RestoreBaseRune(i);
5508
5509 if (runeCost[RUNE_DEATH] == 0)
5510 break;
5511 }
5512 }
5513 }
5514 }
5515
5516 // you can gain some runic power when use runes
5517 if (didHit)
5518 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5519 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5520}
@ RUNE_UNHOLY
Definition: Player.h:410
@ RUNE_BLOOD
Definition: Player.h:409
@ RUNE_MISS_COOLDOWN
Definition: Player.h:404
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:435
void SetLastUsedRune(RuneType type)
Definition: Player.h:2490
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13317
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13346
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1811
uint32 runePowerGain
Definition: DBCStructure.h:1808

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8832{
8834 if (!gcd)
8835 {
8836 // Xinef: fix for charmed pet spells with no cooldown info
8838 gcd = MIN_GCD;
8839 else
8840 return;
8841 }
8842
8843 if (m_caster->IsPlayer())
8845 return;
8846
8847 // Global cooldown can't leave range 1..1.5 secs
8848 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8849 // but as tests show are not affected by any spell mods.
8851 {
8852 // gcd modifier auras are applied only to own spells and only players have such mods
8853 if (m_caster->IsPlayer())
8855
8856 // Apply haste rating
8859 {
8860 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8861 }
8862
8863 if (gcd < MIN_GCD)
8864 gcd = MIN_GCD;
8865 else if (gcd > MAX_GCD)
8866 gcd = MAX_GCD;
8867 }
8868
8869 // Only players or controlled units have global cooldown
8870 if (m_caster->GetCharmInfo())
8872 else if (m_caster->IsPlayer())
8874}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:98
@ MIN_GCD
Definition: Spell.cpp:8816
@ MAX_GCD
Definition: Spell.cpp:8817
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: CharmInfo.cpp:410

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4393{
4394 // update pointers based at it's GUIDs
4395 if (!UpdatePointers())
4396 {
4397 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4398 cancel();
4399 return;
4400 }
4401
4403 {
4404 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4405 cancel();
4406 return;
4407 }
4408
4409 // check if the player caster has moved before the spell finished
4410 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4411 if ((m_caster->IsPlayer() && m_timer != 0) &&
4414 {
4415 // don't cancel for melee, autorepeat, triggered and instant spells
4417 cancel(true);
4418 }
4419
4420 switch (m_spellState)
4421 {
4423 {
4424 if (m_timer > 0)
4425 {
4426 if (difftime >= (uint32)m_timer)
4427 m_timer = 0;
4428 else
4429 m_timer -= difftime;
4430 }
4431
4432 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4433 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4434 cast(!m_casttime);
4435 break;
4436 }
4438 {
4439 if (m_timer)
4440 {
4441 if (m_timer > 0)
4442 {
4443 if (difftime >= (uint32)m_timer)
4444 m_timer = 0;
4445 else
4446 m_timer -= difftime;
4447 }
4448 }
4449
4450 if (m_timer == 0)
4451 {
4453
4454 finish();
4455 }
4456 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4457 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4458 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4459 // Xinef: so the aura can be removed in different updates for all units
4460 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4461 {
4462 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4464 finish();
4465 }
4466 break;
4467 }
4468 default:
4469 break;
4470 }
4471}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3380

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3381{
3382 // Not need check return true
3384 return true;
3385
3386 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3387 uint8 channelAuraMask = 0;
3388 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3390 channelAuraMask |= 1 << i;
3391
3392 channelAuraMask &= channelTargetEffectMask;
3393
3394 float range = 0;
3395 if (channelAuraMask)
3396 {
3398 if (range == 0)
3399 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3400 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3401 {
3402 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3403 break;
3404 }
3405
3406 if (Player* modOwner = m_caster->GetSpellModOwner())
3407 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3408
3409 // xinef: add little tolerance level
3410 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3411 }
3412
3413 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3414 {
3415 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3416 {
3417 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3418
3419 if (!unit)
3420 continue;
3421
3422 if (IsValidDeadOrAliveTarget(unit))
3423 {
3424 if (channelAuraMask & ihit->effectMask)
3425 {
3427 {
3428 if (m_caster != unit)
3429 {
3430 if (!m_caster->IsWithinDistInMap(unit, range))
3431 {
3432 ihit->effectMask &= ~aurApp->GetEffectMask();
3433 unit->RemoveAura(aurApp);
3434 continue;
3435 }
3436 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3439 }
3440 }
3441 else // aura is dispelled
3442 continue;
3443 }
3444
3445 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3446 }
3447 }
3448 }
3449
3450 // Xinef: not all effects are covered, remove applications from all targets
3451 if (channelTargetEffectMask != 0)
3452 {
3453 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3454 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3455 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3456 if (IsValidDeadOrAliveTarget(unit))
3458 {
3459 ihit->effectMask &= ~aurApp->GetEffectMask();
3460 unit->RemoveAura(aurApp);
3461 }
3462 }
3463
3464 // is all effects from m_needAliveTargetMask have alive targets
3465 return channelTargetEffectMask == 0;
3466}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:433
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5516
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:19993
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8214

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7853{
7856 else
7857 {
7860 m_originalCaster = nullptr;
7861 }
7862
7864 {
7866 // cast item not found, somehow the item is no longer where we expected
7867 if (!m_CastItem)
7868 return false;
7869 }
7870 else
7871 m_CastItem = nullptr;
7872
7874
7875 // further actions done only for dest targets
7876 if (!m_targets.HasDst())
7877 return true;
7878
7879 // cache last transport
7880 WorldObject* transport = nullptr;
7881
7882 // update effect destinations (in case of moved transport dest target)
7883 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7884 {
7885 SpellDestination& dest = m_destTargets[effIndex];
7886 if (!dest._transportGUID)
7887 continue;
7888
7889 if (!transport || transport->GetGUID() != dest._transportGUID)
7891
7892 if (transport)
7893 {
7894 dest._position.Relocate(transport);
7896 }
7897 }
7898
7899 return true;
7900}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:118
void RelocateOffset(const Position &offset)
Definition: Position.cpp:58
Position _transportOffset
Definition: Spell.h:105
ObjectGuid _transportGUID
Definition: Spell.h:104
void Update(Unit *caster)
Definition: Spell.cpp:480

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4920{
4921 uint32 ammoInventoryType = 0;
4922 uint32 ammoDisplayID = 0;
4923
4924 if (m_caster->IsPlayer())
4925 {
4927 if (pItem)
4928 {
4929 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4930 if (ammoInventoryType == INVTYPE_THROWN)
4931 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4932 else
4933 {
4935 if (ammoID)
4936 {
4937 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4938 if (pProto)
4939 {
4940 ammoDisplayID = pProto->DisplayInfoID;
4941 ammoInventoryType = pProto->InventoryType;
4942 }
4943 }
4944 else if (m_caster->HasAura(46699)) // Requires No Ammo
4945 {
4946 ammoDisplayID = 5996; // normal arrow
4947 ammoInventoryType = INVTYPE_AMMO;
4948 }
4949 }
4950 }
4951 }
4952 else
4953 {
4954 uint32 nonRangedAmmoDisplayID = 0;
4955 uint32 nonRangedAmmoInventoryType = 0;
4956 for (uint8 i = 0; i < 3; ++i)
4957 {
4959 {
4960 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4961 {
4962 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4963 {
4964 switch (itemEntry->SubclassID)
4965 {
4967 ammoDisplayID = itemEntry->DisplayInfoID;
4968 ammoInventoryType = itemEntry->InventoryType;
4969 break;
4972 ammoDisplayID = 5996; // is this need fixing?
4973 ammoInventoryType = INVTYPE_AMMO;
4974 break;
4976 ammoDisplayID = 5998; // is this need fixing?
4977 ammoInventoryType = INVTYPE_AMMO;
4978 break;
4979 default:
4980 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4981 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4982 break;
4983 }
4984
4985 if (ammoDisplayID)
4986 break;
4987 }
4988 }
4989 }
4990 }
4991
4992 if (!ammoDisplayID && !ammoInventoryType)
4993 {
4994 ammoDisplayID = nonRangedAmmoDisplayID;
4995 ammoInventoryType = nonRangedAmmoInventoryType;
4996 }
4997 }
4998
4999 *data << uint32(ammoDisplayID);
5000 *data << uint32(ammoInventoryType);
5001}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
@ INVTYPE_AMMO
Definition: ItemTemplate.h:280
uint32 DisplayInfoID
Definition: ItemTemplate.h:625
Definition: DBCStructure.h:1140

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4556{
4557 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4558 data << uint32(spellInfo->Id);
4559 data << uint8(result); // problem
4560 switch (result)
4561 {
4563 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4564 break;
4565 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4566 // hardcode areas limitation case
4567 switch (spellInfo->Id)
4568 {
4569 case 41617: // Cenarion Mana Salve
4570 case 41619: // Cenarion Healing Salve
4571 data << uint32(3905);
4572 break;
4573 case 41618: // Bottled Nethergon Energy
4574 case 41620: // Bottled Nethergon Vapor
4575 data << uint32(3842);
4576 break;
4577 case 45373: // Bloodberry Elixir
4578 data << uint32(4075);
4579 break;
4580 default: // default case (don't must be)
4581 data << uint32(0);
4582 break;
4583 }
4584 break;
4586 if (spellInfo->Totem[0])
4587 data << uint32(spellInfo->Totem[0]);
4588 if (spellInfo->Totem[1])
4589 data << uint32(spellInfo->Totem[1]);
4590 break;
4592 if (spellInfo->TotemCategory[0])
4593 data << uint32(spellInfo->TotemCategory[0]);
4594 if (spellInfo->TotemCategory[1])
4595 data << uint32(spellInfo->TotemCategory[1]);
4596 break;
4600 data << uint32(spellInfo->EquippedItemClass);
4601 data << uint32(spellInfo->EquippedItemSubClassMask);
4602 break;
4604 {
4605 uint32 item = 0;
4606 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4607 if (spellInfo->Effects[eff].ItemType)
4608 item = spellInfo->Effects[eff].ItemType;
4609 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4610 if (proto && proto->ItemLimitCategory)
4611 data << uint32(proto->ItemLimitCategory);
4612 break;
4613 }
4615 data << uint32(customError);
4616 break;
4618 {
4619 uint32 missingItem = 0;
4620 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4621 {
4622 if (spellInfo->Reagent[i] <= 0)
4623 continue;
4624
4625 uint32 itemid = spellInfo->Reagent[i];
4626 uint32 itemcount = spellInfo->ReagentCount[i];
4627
4628 if (!caster->HasItemCount(itemid, itemcount))
4629 {
4630 missingItem = itemid;
4631 break;
4632 }
4633 }
4634
4635 data << uint32(missingItem); // first missing item
4636 break;
4637 }
4639 data << uint32(spellInfo->Mechanic);
4640 break;
4642 data << uint32(spellInfo->EquippedItemSubClassMask);
4643 break;
4645 data << uint32(0); // Item entry
4646 data << uint32(0); // Count
4647 break;
4649 data << uint32(0); // SkillLine.dbc Id
4650 data << uint32(0); // Amount
4651 break;
4653 data << uint32(0); // Skill level
4654 break;
4655 default:
4656 break;
4657 }
4658}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:1003
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1130
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1099
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1096
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1050

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5005{
5006 // This function also fill data for channeled spells:
5007 // m_needAliveTargetMask req for stop channelig if one target die
5008 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5009 {
5010 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5011 // possibly SPELL_MISS_IMMUNE2 for this??
5012 ihit->missCondition = SPELL_MISS_IMMUNE2;
5013 }
5014
5015 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5016 // sending more than 255 targets crashes the client (since count sent would be wrong)
5017 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5018 // target conditions but we still need to limit the number of targets sent and keeping
5019 // correct count for both hit and miss).
5020
5021 uint32 hit = 0;
5022 std::size_t hitPos = data->wpos();
5023 *data << (uint8)0; // placeholder
5024 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5025 {
5026 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5027 {
5028 *data << ihit->targetGUID;
5029 // Xinef: No channeled spell checked, no anything
5030 //m_channelTargetEffectMask |=ihit->effectMask;
5031 ++hit;
5032 }
5033 }
5034
5035 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5036 {
5037 *data << ighit->targetGUID; // Always hits
5038 ++hit;
5039 }
5040
5041 uint32 miss = 0;
5042 std::size_t missPos = data->wpos();
5043 *data << (uint8)0; // placeholder
5044 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5045 {
5046 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5047 {
5048 *data << ihit->targetGUID;
5049 *data << uint8(ihit->missCondition);
5050 if (ihit->missCondition == SPELL_MISS_REFLECT)
5051 *data << uint8(ihit->reflectResult);
5052 ++miss;
5053 }
5054 }
5055 // Reset m_needAliveTargetMask for non channeled spell
5056 // Xinef: Why do we reset something that is not set??????
5057 //if (!m_spellInfo->IsChanneled())
5058 // m_channelTargetEffectMask = 0;
5059
5060 data->put<uint8>(hitPos, (uint8)hit);
5061 data->put<uint8>(missPos, (uint8)miss);
5062}
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().